Having spent a lot of time wondering why it's so hard to do permanent redirection in MVC, I came across this page http://www.eworldui.net/blog/post/2008/04/ASPNET-MVC---Legacy-Url-Routing.aspx which made it look moderately straightforward.
I downloaded the sample code, copied all the helper classes into a new MVC project, and added the following to the RouteConfig.RegisterRoutes() method...
routes.Add("Jim1", new LegacyRoute("Default.aspx", "Home", new LegacyRouteHandler()));
The idea was to have requests for /Default.aspx mapped to /Home instead. However, this just gives a 404 in the browser. When debugging, it breaks on the LegacyHandler.ProcessRequest() method on the line that throws an "Invalid Url" exception.
Has anyone used this code that can advise? Or, does anyone have a SIMPLE solution for this? I have an old ASP.NET WebForms site that I've converted to MVC, and want to set up redirection. I can't believe how difficult it is.
Anyone any ideas?
In case it helps anyone, I did some more searching, and found a fairly simple solution that did work.
If you look at this blog post, you'll find a fairly simple approach that requires you to add some classes to your solution. I created a new class library, and added them there. I then referenced this from my MVC project, and added lines like the following to my RegisterRoutes() method...
routes.MapLegacyRoute(null, "Default.aspx", new {controller = "Home", action = "Index"});
routes.MapLegacyRoute(null, "About.aspx", new {controller = "Home", action = "About"});
routes.MapLegacyRoute(null, "Contact.aspx", new {controller = "Home", action = "Contact"});
Worked like a treat!
Hope this helps someone. It would have saved me hours if I had found this earlier!
Related
I'm using Areas to help organize my Web API. I essentially have 2 sets of APIs, one for performing account/user management and the other is using the service that I provide.
So my routing looks like this
"api/{area}/{controller}/{action}/{accountNumber}"
Before I started using Areas, the Help Page was working fine, but after I started using Areas it stopped generating the help documentation. Is there something I need to configure to get Areas to be included by the Help page?
I've used multiple routes to solve the same thing without areas:
config.Routes.MapHttpRoute("Foo",
"api/Foo/{fooId}",
new {controller = "Foo", fooId = RouteParameter.Optional});
config.Routes.MapHttpRoute("Foo_Bar",
"api/Foo/{FooId}/Bars/{barId}",
new {controller = "Bar", barId = RouteParameter.Optional});
Works fine with the HelpPage.
I've also tried AttributeRouting, but I prefer my routes.
I just cant get this to work...
I have the following routes:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("*.html|js|css|gif|jpg|jpeg|png|swf");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
routes.MapRoute(
"Default", // Route name
"{lama}/{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Index", lama = "en-gb" } // Parameter defaults
);
And once I load the page.. I have a img element that tries to retrive the following url:
css/img/backgrounds/slide1_2048x1280.jpg
But the image wont show up and if I check my console I get the following error:
GET {my localhost}/cn/Home/css/img/backgrounds/slide1_2048x1280.jpg 404 (Not Found)
I have such a hard time understanding the route-system.. is there anywhere I can read ALOT more about this?.. And could somebody please help me with this single problem then that whould be very appreciated!
I think have fallen foul of relative urls in your html.
Since you haven't said whether this is Razor or Aspx; I'm just going to go with Aspx.
When you write the img tag it seems that you might be doing:
<img src="[relative_path_to_file]" />, using the path of the img relative to the page.
If that doesn't start with / then it's almost certainly the case that you will end up with issues, especially since MVC URLs don't map to the path of the actual page.
What you want to do is to use Url.Content("~/[full_path_to_file]") which will ensure that an absolute path will always be used.
On another note - you really do not need to write all these ignore routes for files that exist on disk. By default, the routing engine will not route existing files - you have to set routes.RouteExistingFiles = true in the RegisterRoutes method in your global in order to route files that already exist; so I think you should get rid of them.
i usually hit up 1) stackoverflow (obviously!), and 2) the msdn docs are pretty good:
http://msdn.microsoft.com/en-us/library/dd410120.aspx. But i usually end up googling for specifically what i need =)
However, looks like you're trying to setup a route to ignore certain filetypes?
i found this article that gives some good ideas on how to handle this.
I've only blocked one or two filetypes before, and i made one line per filetype. Not sure if you can make one line that has extensions delimited by pipe (|) like you're doing (i could be wrong!)
routes.IgnoreRoute("{*allaspx}", new {allaspx=#".*\.aspx(/.*)?"});
routes.IgnoreRoute("{*allswf}", new {allswf=#".*\.swf(/.*)?"});
I accidentally deleted my app/controllers file on Ruby Rails. How would I get it back? I didn't use git init when I first set it up.
Thanks
You really don't have to start a whole new project if you've permanently lost your controller file. You can do a 'rails g controller ControllerName new index show create etc.'
You'll still have to fill in a lot of the logic, but it's better than starting your whole project over. And for the love of ${DIETY} back up your stuff.
I tried asking this question a bit differently before, but it wasn't understood, so I'll try another way:
I have an MVC 3 application where I have views in the Views directory as usual. However, for various reasons I need the images for each view to be in the same folder as the view itself, i.e. in my case e.g. Views/Manuals/en-US/name
Here's the route I use:
routes.MapRoute(
"Parameter",
"{controller}/{action}/{lang}/{prod}",
new { controller = "Manuals", action = "Product", lang = "en-US", prod = "name" }
);
Now, as mentioned, I need the images for this view to be in the same folder, so that the image path can simply be "ATEXSymbol.svg".
When I just have this route, and use a simple relative path like this for the image, what I get is an error like this:
The view 'da-DK/ATEXSymbol.svg' or its master was not found or
no view engine supports the searched locations. The following
locations were searched: ~/Views/Manuals/da-DK/ATEXSymbol.svg.aspx
~/Views/Manuals/da-DK/ATEXSymbol.svg.ascx
~/Views/Shared/da-DK/ATEXSymbol.svg.aspx
~/Views/Shared/da-DK/ATEXSymbol.svg.ascx
~/Views/Manuals/da-DK/ATEXSymbol.svg.cshtml
~/Views/Manuals/da-DK/ATEXSymbol.svg.vbhtml
~/Views/Shared/da-DK/ATEXSymbol.svg.cshtml
~/Views/Shared/da-DK/ATEXSymbol.svg.vbhtml
So basically, it's looking for the image in the correct language folder, but without the product name folder part, and with one of a number of view extensions appended. I know MVC doesn't really expect this relative path in the same folder, but I pretty much don't have any choice. I'm required to put images in the same folder for purposes out of my hands.
So how can I achieve this?
EDIT:
Actually, I was mistaken a bit above, saying that the product name part of the path was missing, of course it isn't. That part of the path is the name of the view itself. So basically the path I get by a simple relative path (just the name of the image file) in the src attribute creates the correct path for the image. The only problem is that the view file extension is added...
Anyone know how to solve this?
EDIT 2:
BTW, I could have used Url.Content, but for some reason that doesn't work either. If I use this:
<embed type="image/svg+xml" src="#Url.Content("~/Content/images/da-DK/3153/CheckRotation.svg")"></embed>
...it works...but if I use this (same thing but with the image in the Views folder)...
<embed type="image/svg+xml" src="#Url.Content("~/Views/Manuals/da-DK/CheckRotation.svg")"></embed>
...it doesn't work. If I inspect the path in the latter example in the web inspector, it looks like the correct path (localhost:49864/Views/Manuals/da-DK/CheckRotation.svg) but with the message that it cannot be found.
EDIT 3:
The answer by Thinking Sites gave me a solution, I just had to modify it a bit, since I needed the route suggested for the views themselves. So I added this route:
routes.MapRoute(
"Image",
"{controller}/{action}/{lang}/{prod}",
new { controller = "Manuals", action = "Image", lang = "en-US", prod = "name" }
);
I made a slight adjustment in the path (as suggested), since the prod now actually carries the entire filename, including extension:
public ActionResult Image(string lang, string prod)
{
var root = Server.MapPath("~/Views/Manuals/");
var filepath = Path.Combine(root, lang, prod); // whatever creates your path here.
return File(filepath, "image/svg+xml");
}
And then in the view I can have paths like this:
<embed type="image/svg+xml" src="#Url.Content("/Manuals/Image/da-DK/CheckRotation.svg")"></embed>
Using this route:
routes.MapRoute(
"Parameter",
"{controller}/{action}/{lang}/{prod}",
new { controller = "Manuals", action = "Product", lang = "en-US", prod = "name" }
);
Create this action in your controller ManualsController
public ActionResult Product(string lang,string prod){
var root = Server.MapPath("~/views/manuals/");
var filepath = Path.Combine(root,lang,prod,".svg"); // whatever creates your path here.
return File(filepath ,"your mime type");
}
No need for a custom view engine. The FileResult is designed for just this occasion.
Maybe the answer to your question is in your error:
The view 'da-DK/ATEXSymbol.svg' or its master was not found or no view engine supports the searched locations.
Have you thought about plugging in a custom view engine?
I have never created one myself & can't offer guidance, so this is an incomplete answer (I can delete later depending on comments). It's an interesting problem though, and so far as I can tell a unique one. I wonder who would dictate that items be "dumped in en masse" for a framework that doesn't work that way by convention. Pretty straightforward if you were working with web forms though.
I'm trying to create a route for the following urls:
www.mysite.com/user/username
www.mysite.com/user/username/pictures
I tried doing that with the following code:
routes.MapRoute(
"UserProfile",
"user/{sn}/{action}",
new { controller = "User", action = "Index", sn = "" }
);
So if an action is not specified, you go to the index action.
However, it's not working and I'm not sure what I'm doing wrong.
Thanks for any help.
Looks like your code is correct.
The order of the rules is important. Try to place this above all other rules.
And if it will intefere with other rules, you should provide some constraints for the best matches.
I agree with maxnk, the code looks correct, it's probably just an ordering thing. I'd suggest checking out the Route Debugger that Phil Haack wrote: http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx. It's very useful for these tricky route-ordering issues