Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect Url.Action when URL rewrite is used

I get an incorrect URL from the Action method when I use a URL rewrite.

I have this rewrite rule in web.config:

<rule name="Old Objects 2" stopProcessing="true">
  <match url="^transportbilar/(nya|begagnade|miljobilar)/(.*)$" ignoreCase="true"/>
  <action type="Rewrite" url="/transportbilar/{R:2}"/>
</rule>

This will rewrite an URL like /transportbilar/nya/fiat/7s76s8dg to /transportbilar/fiat/7s76s8dg, which works fine, but the Url.Action gets confused by this.

I use an expression like this to create an URL in the page:

url.Action("Slideshow", "Object", new { id = objectId });

When the URL rewrite is not used (browsing directly to the page), this produces the correct URL /Object/Slideshow/7s76s8dg, but when the URL rewrite is used, the Action method adds the first part of the page URL to the generated URL, and produces the incorrect URL /transportbilar/Object/Slideshow/7s76s8dg.

I think that I can do a Redirect in the rewrite rule instead, which would circumvent the problem as the requesting URL would change, but is there a way to make it work without changing it to a Redirect?

Edit:

The routes that I think could possibly be relevant are these (added in this order):

transportbilar/handlare/{id}/{criteria}
transportbilar/handlare
transportbilar
transportbilar/sokresultat/{criteria}
transportbilar/{brand}/{id}/{criteria}
{controller}/{action}/{id}

The last route would catch the url /Object/Slideshow/7s76s8dg and the second from last would catch /transportbilar/fiat/7s76s8dg.

like image 373
Guffa Avatar asked Apr 27 '11 08:04

Guffa


4 Answers

Hmmm.. don't think I can help you get to your rewrite based solution. I'm guessing internally IIS/ASP.NET may be having a problem that you may face when you try to hack a regex mapping in your routes - i.e. URL.Action can't determine the correct reverse mapping from the Controller/Action combination.

You could check what the following say about your URL, and if that gives you any hints as to what the problem is ...

<%= Request.Path %>
<%= Request.RawUrl %>
<%= Request.ServerVariables["HTTP_URL"] %>

... to see if `/transportbilar' is being added that stage.

In any case, I'd seriously go with redirecting the legacy URLs. That approach isolates your actual current system from the legacy, especially since it seems like your route collection is complicated enough already.

like image 163
musaul Avatar answered Sep 29 '22 01:09

musaul


Use routing instead of URL rewrites, you are using MVC after all.

Check this article about routing:

http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx

like image 35
Michel Triana Avatar answered Sep 29 '22 02:09

Michel Triana


Is the Url rewriting stuff for legacy Urls?

Could you perhaps ditch the Url rewrite and using a route with constraints. Something like:

routes.MapRoute(
    "OldObject2",
    "transportbilar/{mycondition}/{make}/{id}",
    new { controller = "Object", action = "Slideshow" },
    new
    {
        mycondition = "nya|begagnade|miljobila"
    }
);

I'm not sure exactly what your app is doing so the above might not make 100% sense but should give you an idea of what I'm thinking...

like image 24
Lee Gunn Avatar answered Sep 29 '22 03:09

Lee Gunn


This worked for me (borrowing a little from another answer):

routes.MapRoute(
    "NewRoute",
    "transportbilar/{make}/{id}",
    new { controller = "Home", action = "Test" }
);
routes.MapRoute(
    "OldRoute",
    "transportbilar/{mycondition}/{make}/{id}",
    new { controller = "Home", action = "Test" },
    new
    {
        mycondition = "nya|begagnade|miljobila"
    }
);

The new one goes first so the helper methods resolve to it. But both go to the same controller and action.

<p>@Html.ActionLink("link", "Test", new { make = "testmake4", id = 5})</p>

On both the old and new URLs this resolves to /transportbilar/testmake4/5

like image 26
RandomEngy Avatar answered Sep 29 '22 02:09

RandomEngy