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

发布于 2024-11-04 01:30:06 字数 1245 浏览 1 评论 0原文

当我使用 URL 重写时,我从 Action 方法获得了不正确的 URL。

我在 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 等 URL 重写为 /transportbilar/fiat/7s76s8dg,效果很好,但是 Url.Action 对此感到困惑。

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

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

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

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

编辑:

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

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

最后一个路线将捕获 url /Object/Slideshow/7s76s8dg ,倒数第二个将捕获 /transportbilar/fiat/7s76s8dg

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)/(.*)
quot; 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无声无音无过去 2024-11-11 01:30:06

嗯..不认为我可以帮助您找到基于重写的解决方案。我猜测当您尝试破解路由中的正则表达式映射时,IIS/ASP.NET 内部可能会遇到一个问题 - 即 URL.Action 无法确定正确的反向映射来自控制器/动作组合。

您可以检查以下关于您的 URL 的内容,如果这给了您任何关于问题所在的提示……

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

以查看该阶段是否添加了“/transportbilar”。

无论如何,我会认真考虑重定向旧版 URL。这种方法将您的实际当前系统与遗留系统隔离开来,特别是因为您的路线集合似乎已经足够复杂了。

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.

别把无礼当个性 2024-11-11 01:30:06

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

查看这篇有关路由的文章:

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

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

拥醉 2024-11-11 01:30:06

Url 是否重写了旧版 Url 的内容?

您是否可以放弃 URL 重写并使用有约束的路由。比如:

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

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

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...

月牙弯弯 2024-11-11 01:30:06

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

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>

在旧的和新的 URL 上,这都会解析为 /transportbilar/testmake4/5

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

冰魂雪魄 2024-11-11 01:30:06

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

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

You can use your these functions to avoid these problems:

    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;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文