Маршрутизация к действиям с теми же именами, но различными параметрами

У меня есть этот набор маршрутов:

        routes.MapRoute(
            "IssueType",
            "issue/{type}",
            new { controller = "Issue", action = "Index" }
        );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

Вот класс контроллера:

public class IssueController : Controller
{
    public ActionResult Index()
    {
        // todo: redirect to concrete type
        return View();
    }

    public ActionResult Index(string type)
    {
        return View();
    }
}

почему, когда я запрашиваю http://host/issue, я добираюсь The current request for action 'Index' on controller type 'IssueController' is ambiguous between the following action methods:
Я ожидаю, что сначала один метод должен действовать, когда нет никаких параметров и второго, когда некоторый параметр указал.

где сделал я сделал ошибку?

UPD: возможный дубликат: действительно ли можно ли перегрузить методы контроллера в ASP.NET MVC?

UPD 2: из-за ссылки выше - нет никакого легального способа сделать перегрузку действия, не так ли?

UPD 3: Методы действия не могут быть перегружены на основе параметров (c) http://msdn.microsoft.com/en-us/library/system.web.mvc.controller%28VS.100%29.aspx

22
задан Community 23 May 2017 в 11:54
поделиться

2 ответа

У меня был бы один метод Index, который ищет допустимую переменную типа

    public class IssueController : Controller  
{  
    public ActionResult Index(string type)  
    {  
        if(string.isNullOrEmpty(type)){
            return View("viewWithOutType");}
        else{
            return View("viewWithType");} 
    }
}

EDIT:

Как насчет создания пользовательского атрибута, который ищет конкретное значение запроса, как в этом посте StackOverflow

[RequireRequestValue("someInt")] 
public ActionResult MyMethod(int someInt) { /* ... */ } 

[RequireRequestValue("someString")] 
public ActionResult MyMethod(string someString) { /* ... */ } 

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute { 
    public RequireRequestValueAttribute(string valueName) { 
        ValueName = valueName; 
    } 
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { 
        return (controllerContext.HttpContext.Request[ValueName] != null); 
    } 
    public string ValueName { get; private set; } 
} 
11
ответ дан 29 November 2019 в 05:44
поделиться

Вы можете сделать это с помощью ActionFilterAttribute, который проверяет параметры с помощью отражения (я пробовал), но это плохая идея. Каждое отдельное действие должно иметь собственное имя.

Почему бы просто не назвать два ваших метода, скажем, «Индекс» и «Один», и жить с ограничением на именование?

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

Если вы хотите [взломать] ActionFilterAttribute, который соответствует параметрам, дайте мне знать, и я отправлю на него ссылку, но, как я уже сказал, это плохая идея.

1
ответ дан 29 November 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: