使用URL重写时,Url.Action不正确

时间:2011-04-27 08:29:01

标签: asp.net-mvc url-rewriting asp.net-mvc-routing

当我使用网址重写时,我从Action方法获取了错误的网址。

我在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>

这会将/transportbilar/nya/fiat/7s76s8dg之类的网址重写为/transportbilar/fiat/7s76s8dg,效果很好,但Url.Action会因此而感到困惑。

我使用这样的表达式在页面中创建一个URL:

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

当不使用URL重写(直接浏览到页面)时,这将生成正确的URL /Object/Slideshow/7s76s8dg,但是当使用URL重写时,Action方法会添加第一部分生成的网址的网址,并生成错误的网址/transportbilar/Object/Slideshow/7s76s8dg

我认为我可以在重写规则中执行重定向,这可以避免问题,因为请求的URL会发生变化,但有没有办法让它工作而不将其更改为重定向?

编辑:

我认为可能相关的路线是这些(按此顺序添加):

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

最后一条路线会捕获网址/Object/Slideshow/7s76s8dg,而最后一条路线会捕获/transportbilar/fiat/7s76s8dg

5 个答案:

答案 0 :(得分:5)

嗯..不要以为我可以帮你找到基于重写的解决方案。我猜在内部IIS / ASP.NET可能会遇到一个问题,当您尝试在路由中破解正则表达式映射时可能会遇到这种问题 - 即URL.Action无法确定Controller / Action的正确反向映射组合

您可以查看以下关于您的网址的内容,以及是否可以提供有关问题的任何提示......

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

...看看是否正在添加“/ transportbilar”。

在任何情况下,我都会认真考虑重定向旧版网址。这种方法将您当前的实际系统与遗留系统隔离开来,特别是因为您的路线收集似乎已经足够复杂了。

答案 1 :(得分:3)

使用路由而不是URL重写,毕竟你正在使用MVC。

查看有关路由的文章:

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

答案 2 :(得分:3)

Url是否会为遗留网址重写内容?

你是否可以放弃Url重写并使用带约束的路由。类似的东西:

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

我不确定你的应用程序到底在做什么,所以上面的内容可能没有100%的意义,但应该让你知道我在想什么......

答案 3 :(得分:1)

这对我有用(从另一个答案借一点):

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"
    }
);

新的首先是帮助方法解决它。但两者都采用相同的控制器和动作。

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

在旧网址和新网址上,这会解析为/transportbilar/testmake4/5

答案 4 :(得分:0)

您可以使用以下功能来避免这些问题:

    public static string UrlAction(string actionName) {
        return String.Format("/{0}", actionName);
    }

    public static string UrlAction(string actionName, string controllerName) {
        return String.Format("/{0}/{1}", controllerName, actionName);
    }

    public static string UrlAction(string actionName, string controllerName, RouteValueDictionary routeValues) {
        string url = String.Format("/{0}/{1}", controllerName, actionName);

        var parameters = routeValues.Select(s => string.Format("{0}={1}", s.Key, s.Value))
            .Aggregate((current, next) => string.Format("{0}&{1}", current, next));

        return url+"?"+parameters;
    }