Параметры URL стандартов маршрутов ASP.NET MVC - PullRequest
0 голосов
/ 21 июня 2011

С кошмаром, надеюсь, я просто тупой.

У меня есть следующие действия контроллера:

<HttpGet()>
Function News() As ActionResult
End Function

<HttpGet()>
Function News(ByVal id As Integer) As ActionResult
End Function

Я хочу, чтобы он был умным, и переходите к первому, если у меня нет идентификатора в URL, и второму, если есть.

Я получил следующую ошибку:

Текущий запрос на действие «Новости» для типа контроллера «MarketsController» неоднозначен> ​​между следующими методами действия: System.Web.Mvc.ActionResult News () по типу TradeChaseMVC.MarketsController Новости System.Web.Mvc.ActionResult (Int32) для типа TradeChaseMVC.MarketsController

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

    routes.MapRoute( _
        "Default2", _
        "{controller}/{action}/{id}",
        New With {.controller = "Home", .action = "Index"},
        New With {.action = "^[a-zA-Z_]+$", .id = "\d{1,8}|"}
    )

    routes.MapRoute( _
        "Default", _
        "{controller}/{action}",
        New With {.controller = "Home", .action = "Index"},
        New With {.action = "^[a-zA-Z_]+$"}
    ) 

Это сработало бы, но это не та же ошибка.

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

Я также думал о создании атрибута для префикса метода ID, чтобы проверить, есть ли там ID, и если он не разрешает этот метод, но я не могу заставить это работать.

Буду признателен за любую помощь. Karl

Ответы [ 2 ]

2 голосов
/ 21 июня 2011

Вы можете решить эту проблему, используя UrlParameter.Optional и nullable id:

routes.MapRoute( _
    "Default2", _
    "{controller}/{action}/{id}",
    New With {.controller = "Home", .action = "Index", id = UrlParameter.Optional},
    New With {.action = "^[a-zA-Z_]+$", .id = "\d{1,8}|"}
)

Function News(ByVal id As Integer?) As ActionResult
    if id.HasValue then 
         ...
    else
        ...
    end if 
End Function
1 голос
/ 21 июня 2011

Нет, проблема в том, что, как только он идентифицирует имя вызываемого действия, вызывающий действие MVC не может выбирать между двумя методами, потому что он не анализирует запрос, чтобы увидеть, какие параметры могут быть связанным.

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

Если вы сделаете это, обязательно украсьте непараметрическую перегрузку с помощью NonActionAttribute, чтобы вызывающий действие не запутался или даже не сделал его закрытым / защищенным.

Обновление

Обновление после наших комментариев - вам не нужно возвращаться к стандартам REST, если вы переименовываете свой метод действия - вы просто делаете свои маршруты более конкретными (заранее извиняюсь - VB.Net даже не мой второйязык!):

<HttpGet()>
<ActionName("AllNews")>
Function News() As ActionResult 
End Function

<HttpGet()>
Function News(ByVal id As Integer) As ActionResult
End Function  

'-- route for single news item with constraint
routes.MapRoute(
  "News",
  "Markets/News/{id}",
  New With { .controller = "Markets", .action = "News" }, 
  New With { .id = "\d{1,8}" });

'-- route for the all news action method
routes.MapRoute(
  "AllNews",
  "Markets/News",
  New With { .controller = "Markets", .action = "AllNews" });

Теперь вам нужно явно указать маршруты, предназначенные для двух методов действия, но по одной и той же схеме URI RESTful.

Все мои службы REST MVC имеют тенденцию использовать гораздо более явныемаршруты, подобные этому, по той же самой причине, которую вы пытаетесь решить.

...