ASP.Net Mvc 3 Метод Url.Action использует значения параметров из предыдущего запроса

Когда Urls автоматически генерируется с помощью помощника Url.Action, если страница содержит строку, похожую на

@Url.Action( "Edit", "Студент" )

Ожидается, что

будет генерировать URL-адрес, например domain/student/edit, и его работу, как ожидалось. Но если запрошенный url содержит некоторые параметры, такие как domain/student/edit/210, приведенный выше код использует эти параметры из предыдущего запроса и генерирует что-то подобное, даже если я не предоставил такой параметр методу Action.

Короче говоря, если запрошенный url содержит какие-либо параметры, любые автоматически сгенерированные ссылки страницы (обслуживаемые для этого запроса) будут включать эти параметры, независимо от того, укажу я их или нет в методе Url.Action.

Что пойдет не так?

Ответ 1

Странно, похоже, не может воспроизвести проблему:

public class HomeController : Controller
{
    public ActionResult Index(string id)
    {
        return View();
    }

    public ActionResult About(string id)
    {
        return View();
    }
}

и внутри Index.cshtml:

@Url.Action("About", "Home")

Теперь, когда я запрашиваю /home/index/123, помощник URL генерирует /home/about, как ожидалось. Нет параметров призрака. Итак, как ваш сценарий отличается?


UPDATE:

Теперь, когда вы уточнили свой сценарий, кажется, что у вас есть следующее:

public class HomeController : Controller
{
    public ActionResult Index(string id)
    {
        return View();
    }
}

и внутри Index.cshtml, который вы пытаетесь использовать:

@Url.Action("Index", "Home")

Если вы запрашиваете /home/index/123, это генерирует /home/index/123 вместо ожидаемых /home/index (или просто / принятых значений по умолчанию).

Это поведение по дизайну. Если вы хотите его изменить, вам придется написать свой собственный помощник, который игнорирует текущие данные маршрута. Вот как это выглядит:

@UrlHelper.GenerateUrl(
    "Default", 
    "index", 
    "home", 
    null, 
    Url.RouteCollection, 
    // That the important part and it is where we kill the current RouteData
    new RequestContext(Html.ViewContext.HttpContext, new RouteData()), 
    false
)

Это создаст правильный URL-адрес, который вы ожидали. Конечно, это уродливо. Я бы рекомендовал вам инкапсулировать его в помощника многократного использования.

Ответ 3

Использовать перегрузку ActionLink, которая использует параметры и подает нуль

Ответ 4

Вы можете зарегистрировать собственный маршрут для этого действия, например:

routes.MapRoute("Domain_EditStudentDefault",
            "student/edit",
            new { 
                controller = MVC.Student.Name, 
                action = MVC.Student.ActionNames.Edit,
                ID = UrlParameter.Optional
            },
            new object(),
            new[] { "MySolution.Web.Controllers" }
        );

вы могли бы использовать url.RouteUrl("Domain_EditStudentDefault") url RouteUrl helper override только с параметром routeName, который генерирует url без параметров.