I'm having a little problem i hope someone can help me with.
on ASP.net MVC 4 (C#) i need to be able to edit the parameters of my route from my controller.
example the request url is
MyController/MyAction/param1/param2
now from MyAction I need to edit the returned url so that it displays
MyController/MyAction/Modifiedparam1/Modifiedparam2
The purpose of this is to translate the parameters that i retrieve from my database from language changes.
Please use redirect result for this (in MyAction on some condition):
return RedirectToAction("MyAction", { param1Name = Modifiedparam1, param2Name = Modifiedparam2 };
Basically you cannot modify url in controller. Urls is something send by the browser to invoke some action. You may just say browser to redirect user to another url.
Don't fight with framework. It will fight back sooner or later. Instead follow mvc principles, redirect from controller action or filters/interceptors to do so.
Related
I'm using default route configuration of domain/controller/action.
For instance, www.domain/Appointment/RequestAppointment calls the Appointment controller and RequestAppointment ActionResult.
I've been often asked by our Marketing folks to build redirects for shorter versions of our URLs for use in social media or on billboards.
So, they would like to see www.domain/Appointment/RequestAppointment as www.domain/appointment.
I don't have an issue doing that, in this case I am just:
//Appointment Controller
public ActionResult Index()
{
return RedirectToAction("RequestAppointment");
}
Now, our SEO person is telling me the new URL (www.domain/appointment) is returning a 302 redirect (which I understand) and that is bad for SEO. They would like a 301.
So, I understand I can return the (desired from SEO viewpoint) 301 redirect by using:
//Appointment Controller
public ActionResult Index()
{
return RedirectPermanent("http://www.domain.com/Appointment/RequestAppointment");
}
It works, but is there a better way or a best practice to handle this? I figure it can't be that uncommon, but I can't find anything.
I will also have to do the same thing with about 10 other unique URLs that fall into the www.domain/controller/action/id format that would be redirected to www.domain/promotion.
You don't need to set up redirects for these. You can set up the Routing engine to automatically map a given URL to a specific controller action, even if it doesn't match the given default structure. Keep in mind, these need to be BEFORE the default route. You can add as many of these as you want, and they will return a 200, not even a 301.
routes.MapRoute("Request Appointment",
"appointment", // <= What you want the URL after "www.domain" to be
new { controller = "Appointment", action = "RequestAppointment" });
Bear in mind, with this in place, you would need to have the URL be "appointment/index" if you want to get to the index action. However, the same holds true with any other sort of mapping. But, you can get to the same page with both of the following URLs with no server or client redirects occurring:
www.domain.com/appointment
www.domain.com/appointment/requestappointment
I know this can be done, but don't even know what its called to find a good tutorial from Google. I am using ASP.Net MVC4 and I have a controller called ePage, right now I can access what I want from a URL like this
http://www.myUrl.com/ePage/{ACTION}/{PARAMETER as "id"}
how can I change the routing so that (just for this controller if possible) it is read like this
http://www.myUrl.com/ePage/{PARAMETER}
I will always be using "Index" as Action for now.
If there is a simple answer to do that'd be awesome , if not just a point to the right direction for me to read and figure out.
In your Global.asax.cs under the RegisterRoutes method, you can try adding:
routes.MapRoute("MyNewRoute", "ePage/{param}", new {
controller = "ePage",
action = "Index",
});
Your Index method must have an argument named param so that the routing will match.
I am learning MVC 3 after hours right now and last night I ran into an issue that seems like it would be very simple to solve but I can't seem to locate a solution for it.
I have a simple contact form. The end user fills out the form and submits it. When they submit the form I redirect the end user to a different action in the same controller which renders an "inquiry submitted" page/view which is basically a "Thank you page".
The controller is setup like so.
public ActionResult ContactUs()
{
return View();
}
[HttpPost]
public ActionResult ContactUs(ContactInfo contactInfo)
{
if (!ModelState.IsValid)
{
return View();
}
//perform some business logic
return RedirectToAction("InquirySubmitted",contactInfo);
}
public ActionResult InquirySubmitted(ContactInfo contactInfo)
{
return View(contactInfo);
}
The problem:
I do not want end users navigating directly to the InquirySubmitted action via the browser.
I only want the ContactUs action in the controller to be able to send users to the InquirySubmitted View.
I have attempted to make the InquirySubmitted action private so that only the controller can call it like so:
private ActionResult InquirySubmitted(ContactInfo contactInfo)
But this produces an error which I fully understand because I am forcing the browser to request InquirySubmitted by using RedirectToAction().
So my question is simply: What is the best "MVC 3 style" solution to this issue.
You will need to put logic in your InquirySubmitted ActionResult in order to prevent users from viewing the page if they are not supposed to.
You are already passing the InquirySubmitted method your model (ContactInfo). Could you simply inspect the data passed to the method and if it is absent then redirect the user to an error page (or some other page of your choice)?
An alternate solution would be to set a boolean in session that indicates that the user completed the "ContactUs" form. Then you could check for that session object within InquirySubmitted.
First, I would have to say.. Who cares if someone can navigate directly to the Inquiry submitted page? Is there any confidential information, or something sensitive there? If not, so what? What does it hurt?
However, if you're determined to do so. The answer to your question of "How to make an action not accessible directly from the browser" is that You can simply use Html.Action() to render the page, and then decorate the action method with a [ChildActionOnly] attribute.
This doesn't actually solve the problem though, since making the action indirectly accessible only answers your question, not solves your problem. Ultimately, you need to redirect the user to a url to load the page, so you will need some logic that determines if they can view the page or not. This is
Not sure if this still applies in MVC3, but in MVC2 it worked.
your global.asax file has your url structuring in it. You can add your InquirySubmitted to the list of urls that isn't accessible there.
I have an existing site that I'd like to convert to use routing, and after reading Scott Guthrie's post here, I built a working sample that works for most circumstances. However, since not all of the pages on the existing site match a particular pattern, I'll need to check against a database to determine which route (destination .aspx page) to use.
For example, most pages are like this:
http://www.mysite.com/people/person.html
This is fine - I can easily route these to the view_person.aspx page because of the 'people' directory.
But some pages are like this:
http://www.mysite.com/category_page.html
http://www.mysite.com/product_page.html
This necessitates checking the database to see whether to route to the view_category.aspx page or the view_product.aspx page. And this is where I'm stuck. Do I create an IRouteHandler that checks the database and returns the route? Or is there a better way? The only code I've found that kind of fits is the answer to this question.
Thanks in advance.
If you don't mind doing so, the cleanest solution is to:
http://www.mysite.com/pages/category_page.html
In ASP.NET MVC, this situation would be handled a little differently, by specifying a default controller and action method on the root route.
Your route handler doesn't check the database. It sends all the requests to a handler .aspx script. It's that script that checks the database.
My register route looks like...
private static void RegisterRoutes()
{
Route currRoute = new Route("{resource}.axd/{*pathInfo}",
new StopRoutingHandler());
RouteTable.Routes.Add( "IgnoreHandlers", currRoute);
currRoute = new Route("{urlname}",
new EPCRouteHandler("~/Default.aspx"));
currRoute.Defaults = new RouteValueDictionary {{"urlname", "index.html"}};
RouteTable.Routes.Add( "Default", currRoute);
}
The custom handler, which shouldn't be needed in ASP.Net 4.0, simply passes the urlname parameter to the responding script as a URL variable.
Now how often the responding script checks the database depends on how often the data in the database is changed. You can easily cache paths and invalidate the cache when the data is suppose to have changed for instance.
For anyone stuck in the same situation, I ended up adapting the code from this answer to check against a database and return the proper ASPX page.
I am fairly new to MVC but not sure exactly which Redirect... replaces the standard redirect used in WebForms is the standard Response.Redirect()
For instance, I need to redirect to other pages in a couple of scenarios:
WHen the user logs out (Forms signout in Action) I want to redirect to a login page.
In a Controller or base Controller event e.g. Initialize, I want to redirect to another page (AbsoluteRootUrl + Controller + Action)
It seems that multiple redirects get called in some cases which causes errors, something to do with the fact a page is already being redirected? How can cancel the current request and just redirect?
Update:
The answer to this question (System.Web.Mvc.Controller Initialize) indicates that Initialize should not be used and OnActionExecuting should be used?
Any comments on why Initialize should not be used or why OnAuthorization is not a better option?
More Info:
This blog post (http://blog.wekeroad.com/blog/aspnet-mvc-securing-your-controller-actions/) indicates that OnActionExecuting is useful for authentication (as indicated in the link above) I guess adding this to that event in the base Controller class is fine as every page runs an Action in MVC so shouldn't make much difference and having the ability to redirect should be easier. This does make sense, but it also seems to make sense to me that things could be done in an event before this event and makes we question what those events are for? Will be giving OnActionExecuting a go..
1) When the user logs out (Forms signout in Action) I want to redirect to a login page.
public ActionResult Logout() {
//log out the user
return RedirectToAction("Login");
}
2) In a Controller or base Controller event eg Initialze, I want to redirect to another page (AbsoluteRootUrl + Controller + Action)
Why would you want to redirect from a controller init?
the routing engine automatically handles requests that come in, if you mean you want to redirect from the index action on a controller simply do:
public ActionResult Index() {
return RedirectToAction("whateverAction", "whateverController");
}
1) To redirect to the login page / from the login page, don't use the Redirect() methods. Use FormsAuthentication.RedirectToLoginPage() and FormsAuthentication.RedirectFromLoginPage() !
2) You should just use RedirectToAction("action", "controller") in regular scenarios..
You want to redirect in side the Initialize method? Why? I don't see why would you ever want to do this, and in most cases you should review your approach imo.. If you want to do this for authentication this is DEFINITELY the wrong way (with very little chances foe an exception)
Use the [Authorize] attribute on your controller or method instead :)
UPD:
if you have some security checks in the Initialise method, and the user doesn't have access to this method, you can do a couple of things:
a)
Response.StatusCode = 403;
Response.End();
This will send the user back to the login page.
If you want to send him to a custom location, you can do something like this (cautios: pseudocode)
Response.Redirect(Url.Action("action", "controller"));
No need to specify the full url. This should be enough.
If you completely insist on the full url:
Response.Redirect(new Uri(Request.Url, Url.Action("action", "controller")).ToString());
RedirectToAction("actionName", "controllerName");
It has other overloads as well, please check up!
Also, If you are new and you are not using T4MVC, then I would recommend you to use it!
It gives you intellisence for actions,Controllers,views etc (no more magic strings)