Неправильный Url.Action при использовании перезаписи URL

Я получаю неправильный 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>

Это перепишет такой URL как /transportbilar/nya/fiat/7s76s8dg to /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.

Я думаю, что вместо этого я могу сделать Redirect в правиле перезаписи, что бы обойти проблему по мере изменения URL-адреса запроса, но есть ли способ заставить его работать, не меняя его на перенаправление?

Edit:

Пути, которые, по моему мнению, могут быть релевантными, следующие (добавлены в этом порядке):

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

Последний маршрут будет улавливать URL /Object/Slideshow/7s76s8dg, а второй из последнего будет ловить /transportbilar/fiat/7s76s8dg.

Ответы

Ответ 1

Хммм.. не думаю, что я могу помочь вам добраться до вашего решения на основе перезаписи. Я предполагаю, что внутри IIS/ASP.NET может возникнуть проблема, с которой вы можете столкнуться, когда пытаетесь взломать отображение регулярных выражений в ваших маршрутах, т.е. URL.Action не может определить правильное обратное отображение из комбинации Controller/Action.

Вы можете проверить, что говорят о вашем URL-адресе, и если это дает вам какие-то подсказки относительно проблемы...

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

... чтобы увидеть, добавляется ли `/transportbilar 'этот этап.

В любом случае, я бы серьезно пошел с перенаправлением устаревших URL-адресов. Этот подход изолирует вашу текущую систему от наследия, тем более, что кажется, что ваша коллекция маршрутов уже достаточно сложна.

Ответ 3

Является ли URL-адрес перезаписи для устаревших адресов?

Не могли бы вы перерезать Url-переписать и использовать маршрут с ограничениями. Что-то вроде:

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

Я не уверен точно, что делает ваше приложение, поэтому вышеизложенное не может сделать 100% -ный смысл, но должно дать вам представление о том, что я думаю...

Ответ 4

Это сработало для меня (заимствуя немного от другого ответа):

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

Ответ 5

Вы можете использовать эти функции, чтобы избежать следующих проблем:

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