Невозможно заставить ActionLink или RouteLink создать правильный URL - PullRequest
2 голосов
/ 05 июня 2011

Я новичок в ASP.NET MVC (работаю с версией 3) и не могу заставить ActionLink или RouteLink работать, как я ожидаю.В этом приложении событие может иметь много действий, и я хочу направить их, используя:

/Event/1/Activity
/Event/1/Activity/Index  (same as previous)
/Event/1/Activity/Details/5

HTML, сгенерированный этими двумя помощниками, всегда выглядит так:

/Event/1

Вот код ...

Просмотреть Razor HTML

@Html.RouteLink("View Sessions", "SubControllerIndex",
    new { eventId = Model.Id, controller = "Activity", action = "Index" })
@Html.ActionLink("View Sessions", "Index", "Activity", new { eventId = Model.Id }, null)

Отображения маршрутов

routes.MapRoute(
    "SubControllerIndex",
    "Event/{eventId}/{controller}",
    new { controller = "Activity", action = "Index" },
    new { eventId = @"\d+" }
);
routes.MapRoute(
    "ActivityIndex",
    "Event/{eventId}/{controller}/{action}/{id}",
    new { controller = "Activity", action = "Index", id = UrlParameter.Optional },
    new { eventId = @"\d+", id = @"\d*" }
);
routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
    new { id = @"\d*" }
);

Контроллер активности

public ActionResult Index(long eventId)
{
    var activities = _context.Activities.Where(a => a.Event.Id == eventId).ToList();
    return View(activities);
}

Есть идеи, что я тут не так делаю?

Ответы [ 4 ]

5 голосов
/ 05 июня 2011

Причина, по которой система маршрутизации генерирует /Event/1 вместо /Event/1/Activity/Index для маршрута

routes.MapRoute(
   "ActivityIndex",
   "Event/{eventId}/{controller}/{action}/{id}",
   new { controller = "Activity", action = "Index", id = UrlParameter.Optional },
   new { eventId = @"\d+", id = @"\d*" }
);

, заключается в том, что при создании URL-адресов система не будет включать в URL-адреса значения по умолчанию.В этом случае значением по умолчанию контроллера является активность, а значением действия по умолчанию является индекс.Таким образом,

@Html.RouteLink("View Sessions", "SubControllerIndex",
    new { eventId = Model.Id, controller = "Activity", action = "Index" })

сгенерирует /Event/1 вместо /Event/1/Activity/Index.Если вы нажмете на ссылку, вы все равно должны перейти к методу действия Index в ActivityController.

1 голос
/ 14 ноября 2013

Я столкнулся с этим, когда пытался (и пытался и пытался) найти ответ, почему мои пользовательские реализации RouteBase не работали на исходящих маршрутах (те, которые генерируют URL), когда я переключил проект на использование областей.

Я, наконец, наткнулся на ответ при анализе исходного кода MVC: вам нужно заставить свои пользовательские реализации RouteBase реализовывать IRouteWithArea, чтобы инфраструктура знала, к какой области принадлежат ваши пользовательские маршруты.

public class CustomRoute: RouteBase, IRouteWithArea
{
    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
         // Implement custom virtual path (url) here
    }

    #region IRouteWithArea Members

    public string Area
    {
        get { return "Store"; }
    }

    #endregion
}
1 голос
/ 05 июня 2011

Как указывает mrydengren, методы ActionLink и RouteLink удаляют параметры, которые совпадают со значениями по умолчанию.Затем URL-адреса должны указывать на действие, на которое вы указываете.

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

// Either add this at the end as a new route, or replace the one you already have.
routes.MapRoute("ActivityIndexWithoutParams",
    "Event/{eventId/controller/action/id},
    new{},
    new{ eventId = @"\d+", id = @"\d*"}
    );

Теперь вы можете использовать метод RouteLink для создания правильного маршрута:

@Html.RouteLink("View Sessions", "ActivityIndexWithoutParameters",
    new {eventid = Model.Id, controller = "activity", action = "index"}
    );
0 голосов
/ 05 июня 2011

Помните, что маршруты «жадные», и первое совпадение будет тем, которое обрабатывается, поэтому вам нужно потерять этот первый вход в маршрут, иначе второй никогда не будет достигнут.

ЭтоЕдинственное изменение, которое, как я вижу, вам нужно внести, в противном случае добавьте ссылку на действие в представление следующим образом:

@Html.ActionLink("View Sessions", "Details", "Activity", new { eventId = 12, id = 22 }, null)

И вы должны увидеть, что в ссылке генерируется правильный URL.

...