MVC3 Reverse Routing - asp.net-mvc-3

I'm working on a project converting older .aspx pages to newer MVC pages. I'm currently using the routing function to map the existing legacy pages to use the newer MVC pages behind the scenes. This is working great because it is preserving the existing URL, however, whenever the controller needs to redirect the user OR an MVC Url.Action link is used, the URL it sends the user to is the MVC url and not the routed legacy page url. I realize that this is how its suppose to be functioning out of the box but I was wondering if MVC has "reverse routing" functionality of some sort. By reverse routing I am looking for something that allows the Url.Action("action") to return the routed .aspx associated url with the specified action instead of the default /controller/action link.
So for instance,
here is a sample route
context.MapRoute("AboutUs", "pages/aboutus.aspx", new { controller = "default", action = "aboutus" });
This enables domain.com/pages/aboutus.aspx to run the new MVC action "aboutus" from the DefaultController behind the scenes perfectly.
However, if on another MVC page I have a link created by
Url.Action("aboutus")
it points them to domain.com/mvc/aboutus. I would like it to point them to domain.com/pages/aboutus.aspx to keep uniformity across the site.
Thanks for any insights that you can provide. I might end up having to override the Url.Action method to look up the route and return the mapped url but I just wanted to check for existing functionality so I don't reinvent the wheel.

Try using the RouteUrl extension method, which matches the route by route name rather than route parameters, like so:
Url.RouteUrl("aboutus") // route name
MSDN: http://msdn.microsoft.com/en-us/library/dd460347

Related

Transfer request to MVC controller or View

I have an http handler which picks up all requests for my custom extension .page . This works fine with old fashion asp.net where I simply do a Server.Transfer to the aspx file of choice.
However, I would like to move this to MVC and instead reroute to either a Controller or a View. Doesn't matter which though I would prefer to a Controller.
Any help on this subject is appreciated.
Thanks!
I'd go about adding a new entry in the RouteTable.Routes ignored routes:
routes.Ignore("{*allcustomextension}",
new {
allcustomextension = #".*\.ext(/.*)?"
});
This will allow the handler to be invoked as a physical resource.
To redirect from the handler context to a View use:
System.Web.Mvc.UrlHelper.Action("ViewName", "ControllerName");
Firstly, you should redirect only to a controller which will select the view to render but think that you don't need that custom handler. Try something like that (you should change it somehow to match the url format you have)
routes.MapRoute("page", "{controller}/{action}.page");
If that doesn't work and you really want to redirect from your handler, combine the ignoring route from Xander with
Response.Redirect(System.Web.Mvc.UrlHelper.Action("ActionName", "ControllerName"));
Afaik, Server.Transfer works only with asp.net classic so your only option is a redirect.

What are some best practices for detecting mobile devices in mvc3

I am enabling one of my sites to redirect certain pages to mobile versions. Ive read blog posts by Steve Sanderson and Shiju Varghese regarding Attribute usage and 51degrees.mobi.
What I would like to have happen is a given page, dealer-locator, redirect to /mobile/dealer-locator if the device is a mobile device. To accomplish this, I have set up an Area with the dealerlocator controller and the necessary views. Ive tested the code directly and it seems to work properly.
When I visit the site from an actual device or FF with the user agent changed to iPhone 3.0, I get redirected to /mobile. Is there a simple way to map page routes to mobile routes?
I should mention that the site uses isapi_rewrite and the page in question has rules that map /dealer-locator to /dealerlocator and dealerlocator is a controller.
Ive also noticed that form posts don't appear to work properly so it does a get for now.
From Shiju Varghese's blog post (which your question mentions), the method of the RedirectMobileDevicesToMobileAreaAttribute class:
// Override this method if you want to customize the controller/action/parameters to which
// mobile users would be redirected. This lets you redirect users to the mobile equivalent
// of whatever resource they originally requested.
protected virtual RouteValueDictionary GetRedirectionRouteValues(RequestContext requestContext)
{
return new RouteValueDictionary(new { area = "Mobile", controller = "Home", action = "Index" });
}
can be overridden to take care of this.
In his example, everything appears to be sent to ~/Mobile/Home/Index, but you can send the request anywhere. He's creating a new route table, equivelant to the one you'd define in Global.asax.cs for your non-mobile routes. You could either replace your entire route table, or loop through your existing routes and return a dictionary that only contains the mobile equivelants.

How to get a default html page on MVC3 site

I have added an MVC3 web application to an existing website that consists of plain old html files. This works great when you request a specific file but what didn't occur to me was that by changing the site to use .Net 4 it no longer took any notice of the default documents setting in IIS (IIS 6 in this case). So for example I can request www.something.com/index.html but if I request www.something.com I get a resource not found error page. Is there a MapRoute in Global.asax I can specify to map the site route url to index.html?
Looks like something has changed, I had to do
routes.IgnoreRoute("");
ASP.NET complained about the route starting with "/"
routes.IgnoreRoute("");
Allows the request to fall through to the default documents defined in the site configuration. I only have a single controller and route in this project that I use for ajax requests from the client. I want the rest of the site to continue to behave as it did when it was just plain html. With routes.IgnoreRoute("") the MVC3 app ignores the request which allows IIS to return the default document. Thanks all for your suggestions.
in global.asax you can try to define a rules like this one
routes.MapRoute("", "index.html", new { controller = "Home", action = "Index" });
But I'm afraid that with IIS 6 you have to handle the Wild card mapping.
That's normal. IIS 6.0 does not support extensionless urls. You will need a wildcard mapping as explained by Phil Haack.

Always need Https to a particular route

I have MVC3 application with SSL. I want particular page URL should always add Https. Can someone tell me how to do this. Below is the Route in Global file.
routes.MapRoute("root22",
"paybill",
new { controller = "Home", action = "PayBill" });
One more thing if my URL has https in front than should all the paths in the page also use https or not necessary?
You don't need to mess with the routing to accomplish this. Just use the [RequireHttps] attribute on your controller/actions.
[RequireHttps]
public ViewResult YourAction()
If it can, it will redirect to https. Your outgoing links don't have to use https, but when loading javascript, css, images, etc. then it should otherwise the user may get a mixed content security warning.
Above attribute works fine if you want your whole website in https after redirecting using that particular action.
But you want to secure only a single page rather than whole website, just use below code.
http://www.codehosting.net/blog/BlogEngine/post/More-fiddling-with-MVC3-and-https.aspx

mvc 3 razor view engine using "default" views

i'm using Razor for a new project in my company, and i have been playing with it for 2 days and already found some weird behaviour imho.
I have a home controller in the root of my webapp and a home controller in an area , call it Area1. In both these controllers I have an Index action and therefore I got an Index view in the Views root folder, and another one in the Area1\Views folder. If I remove the index view within the area , so Area1\Views\Index.cshtml and I request Area1\Home\Index, I don't get an error about the view engine not finding the view for that action , but the "base" Index view is found in \Views\Index.cshtml and rendered.
Someone knows if this is a bug or it's done by purpose ? If so, there's any way to disable this default ?
Definitely NOT a bug.
This behaviour allows easy reuse of View templates, eg, for error handling.
The default behaviour for ASP.NET MVC is that if you do...:
return View();
...it searches for the view template with the name of the action to use in a number of places: the default naming convention folder for the controller, ie, /Area1/Views/Home/, then /Area1/Views/Shared/ then Area1/Views/ then /Views/Shared/ then /Views/
If it finds no such View matching the name of the action, then it throws an error.
So much for the default behaviour. To "customize" this behaviour, you just need to do the following:
In your controller actions, you can specify the name of the View template to use when you return. EG:
return View("MyOtherView");
or better still, if using T4MVC:
return View(MVC.Area1.Home.Views.MyOtherView); // does away with "magic" strings
As a result, I don't see that you need to switch off the default behaviour to be able to do (whatever) you want. Controllers are there to, uhmmmm, control what views are used to display to the user. That is the best practice.
However, ASP.NET MVC is very configurable, so there are ways and means, I presume, to switch this off.
If you want to do this, good luck to you, but it makes much more sense to follow the defaults and get to understand how ASP.NET MVC works, especially if you are a beginner.
NOTE:
The above applies to ASP.NET MVC 1, 2, 3 and will continue to do so. It is the default behaviour for all View engines, including Razor and WebForm Views.
PS:
And you can configure the urls using route registration if your concern is the look of the url in the user's browser.

Resources