MVC 5: Obtaining the Refering URL - asp.net-mvc

The controller class in MVC 5 apparently does not implement the Request.UrlReferrer as this property is always null and the VS says
When overridden in a derived class, get's information about the referrer URL ...
I check the ServerVariable and the Headers properties by serializing them as XML files to explore their contents and I did not found any key that returns the referring URL.
I already know how to manually handle this for example by TempData, Keeping the URL in session, ActionFilterAttribute for that. I'm not after any of these.
I simply wanna know if such behavior is implemented in MVC 5 by default and if so where I can find it.
The answers in other StackOverFlow posts are outdated

Request.UrlReferrer will give you a Uri object when you are visiting the current page from a link in another web page. If you are directly accessing the url ( as you do when you hit F5 button in Visual studio), you will get a null value as the return value of Request.UrlReferrer call as there we are directly going to this page.
To verify this you can do this.
Have 2 action method
public ActionResult Index()
{
var r = Request.UrlReferrer;
return View();
}
public ActionResult About()
{
return View();
}
Now in the about view(~/Views/Home/About.cshtml), add this makrup to generate a link to your index action.
#Html.ActionLink("Index","Index","Home")
Put a breakpoint in the Index action so you can inspect the r varibale value.
Run your app. Go to About page, Click on your Index link and see what value you get in the r variable when the breakpoint hits the Index action.

Related

Umbraco: Check if page is marked as protected and redirect to login

In my DocType i have a property by the name of "membersOnly" (true/false).
When checked, I want to check, if the user is logged in, if not, redirect to login page with a referrer.
But what is the best way to do this - I dont want to have it in my Master template. How can I hook into the request pipeline, check if the "membersOnly" field excist, and if it does, and it is checked, and the user is not logged in, redirect the user?
Any short snippets out there?
Also, I am aware of the built-in Umbraco way of doing this. But for this case, i need it to be just a simple checkbox on the page in the backend - but the functionality that it fires, is basicly the same, as if i used the built-in Umbraco way in the backend.
You can do this using route hijacking then checking authentication through your controllers. However, if all you have to do is check for authentication, it might be a little bit of an overkill to do route hijacking for your doc types.
Essentially, to do route hijacking, you create a controller with the same name as your doctype, so if your doctype is "memberPage", your controller would look like this:
public class MemberPageController : RenderMvcController
{
public ActionResult Index(RenderModel model)
{
return base.Index(model);
}
}
Notice how it must inherit RenderMvcController in order to work.
Before returning the base RenderMvcController method "Index", you can now run code, e.g. to check authentication.
So you could do this:
public ActionResult Index(RenderModel model)
{
if (Members.IsLoggedIn())
{
return base.Index(model);
}
else
{
return Redirect("~/");
}
}
The cleanest way to implement this yourself, would probably be by creating a custom filter derived from Authorization​Filter​Attribute (located in System.​Web.​Http.​Filters).
Having the derived object use the umbracocontext and query the settings based on the current page.
Umbraco does exactly the same for their custom validation, for some inspiration check out MemberAuthorizeAttribute at github

Temp data is not being maintained between two controllers sitecore

I am just trying to implement Post-Redirect-Get pattern in my sitecore application.
I could see Tempdata is not maintained when i redirect from one controller to another controller.
[HttpPost]
public ActionResult Select()
{
TempData["SelectPost"] = "SomeValue";
var path = PaymentPath;
return RedirectToRoute(MvcSettings.SitecoreRouteName, new { pathInfo = path});
}
public ActionResult Payment()
{
var tempDataValue = TempData["SelectPost"];
//Value is coming as null always
}
I even tried with RedirectToAction and Redirect and also by explicitly calling TempData.keep()
All my pages are controller renderings.
Am i missing anything? I am using Sitecore.NET 7.0. (rev. 130424)
TempData is available to the current and next request only. So if you POST to /select and redirect to /payment (GET) the TempData value will be available.
In your example it looks like you are redirecting to the SitecoreRouteName and then redirecting to /payment, in which case your TempData value will no longer be available.
If you need to store something for longer than the current and next request I suggest you use Session, a cookie or a database to store your value.

ASP.NET MVC catch URL parameter in Controller

I've defined such a controller ViewProfile.
I want to use it for the next syntax to access public user info in my project.
/ViewProfile/Sammy
/ViewProfile/Billy
etc...
But I don't know how to handle the 2-nd parameter in URL.
I've tried to use:
[HttpGet]
public ActionResult Index(string query)
{
...
return View();
}
But in the debugger, string query is always empty.
I have read about routines mapping, but really don't understand how would it help me with the determination of id or other parameters.
I read in ASP.NET MVC Book that to get the parameter directly in the controller action just name it as ID.
ASP.NET MVC lets you easily do this without having to confi gure
anything extra. ASP .NET MVC’s default routing convention is to treat
the segment of a URL after the action method name as a parameter named
ID. If your action method has a parameter named ID, then ASP.NET MVC
will automatically pass the URL segment to you as a parameter.
I just tried a sample app and it worked fine for me. The string i entered in the URL did get passed on to the ID parameter in the action.
Also what i noticed is that you should provide your URL as viewprofile/index/1 or
viewprofile/index/somestring.
YOu seem to be skipping the action part.

How can I make an MVC POST return me to the previous page?

I have the following action which is called from a screen with a list of records.
[HttpPost]
//[Authorize(Roles = "admin")]
public ActionResult Edit(EditViewModel itemView)
{
Once the action has completed I would like to return to the page where the action was called from. However I don't want to refresh that page. I just want to go back to the populated screen using something similar to the "Previous" button in the browser. Right now when I click "save" my action does the following which is not what I want:
return RedirectToAction("Index");
Is there some way to Redirect to previous page with MVC3?
Something like the Stackoverflow functionality after I click edit to edit an answer where it returns to the post.
Instead of a redirection,
[HttpGet]
public ActionResult Index()
{
/// preform any processing necessary for your index page on GET
return View("Index");
}
[HttpPost]
public ActionResuit Edit(EditViewModel itemView)
{
if (ModelState.IsValid)
{
/// do whatever you want with your model...
}
// return the contents as they'd be rendered by the Index action
return Index();
}
Note that with this method the URL in the browser will still display the Edit url (like /area_name/edit), but you can fix that by:
Using a redirect (which you've said you don't want to do)
Using JavaScript to update the URL, or use history.back() as #AlanStephens suggested
Probably other methods that don't immediately come to mind.
However, I'd question whether this is really the best approach. Typically, users expect different URLs to do different things.
Or, if I understand you correctly and the edit action is being called from the Index page,
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost] /// from a form on Index
public ActionResult Index(EditViewModel model)
{
if (ModelState.IsValid)
{
////
}
return View();
}
and just take the /Edit out of play entirely. Again, I don't really care for this approach.
Based off the code you've given, it looks like you've got a paginated screen, with the ability to click edit on each row. Here's how I've solved this problem in the past.
On the Index page, when the page loads, whether it be from the main index or a paging method, add the following:
Session["CurrentUrl"] = Request.Url.ToString();
So now, at the end of the POST method for your edit page, do:
return Session["CurrentUrl"] == null ?
Index() :
Redirect(Session["CurrentUrl"]);
What you described is easily achieved using ajax calls. That way you perform whatever action you like and afterwards (on successful response), you can easily navigate from the current page, using javascript.
If you POST to a page and in response you return the same view you receive with a GET request (index page), then some users might hit F5 to reload that index page and get a warning in the browser, which actually says it will send the POST request again. This is pretty confusing for users and not really user friendly (not to mention numerous concerns related to idem-potency of it).
Although you don't like the redirect approach, because of the additional response, I guess, I should say that, in MVC, this is the correct way to do it, assuming you don't want to use ajax calls.

RedirectToAction problem

I have a Controller: AdminPageController, in which I have the following actions: Index, Create, Save
My save action is as follows:
public ActionResult Save(string[] inputs, int columnsCount)
{
.....
return RedirectToAction("Index");
}
I can see that the debugger passes throug the redurectToAction , but the index is not displayed. I can see that the routing is written as follows:
http://localhost:55405/AdminPage/Create#
What is wrong and how can I solve it?
Please use this utility displays the route data pulled from the request of the current request in the address bar. So you can type in various URLs in the address bar to see which route matches.
http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

Resources