2015-12-16 2 views
1

У меня есть этот контроллер:MVC маршрутизации вопрос: Нулевой вход

public class TestController : Controller 
{ 
    // GET: Test 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    public ActionResult Edit(int accessLevel) 
    { 
     return View(); 
    } 
} 

указан в RouteConfig.cs как:

routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{id}", 
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

routes.MapRoute(
    name: "Test Edit", 
    url: "Test/Edit/{accessLevel}", 
    defaults: new { controller = "Test", action = "Edit", accessLevel = UrlParameter.Optional } 
); 

Если я иду к этому URL:

http://localhost:35689/Test/Edit/2 

Я получаю эту ошибку:

The parameters dictionary contains a null entry for parameter 'accessLevel' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'MyProject.Mvc.Client.Controllers.TestController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

Любая идея, почему это так? Я думаю, что я предоставляю нужный тип данных с /2.

+0

Просто используйте AttributeRouting и вырежьте дерьмовую сломанную таблицу маршрутизации. – Phill

+0

Я пробовал на самом деле, но я получаю тот же результат, не могли бы вы предоставить образец? – Spikee

+0

Не могли бы вы поменять свой маршрут в RouteConfig и попробовать его – Dilip

ответ

8

Определенное определение маршрута должно быть определено до общего значения по умолчанию. Порядок определения маршрутов действительно имеет значение.

routes.MapRoute(
    name: "Test Edit", 
    url: "Test/Edit/{accessLevel}", 
    defaults: new { controller = "Test", action = "Edit", 
                accessLevel = UrlParameter.Optional } 
); 

routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{id}", 
    defaults: new { controller = "Home", action = "Index", 
                  id = UrlParameter.Optional } 
); 

Если вы держите другой порядок, как то, что у вас есть (Generic-умолчанию первый, конкретный один позже), когда приходит запрос на Test/Edit/2 Он будет согласован с общим определением маршрута, поскольку Test является действительным контроллером и Edit - допустимое имя метода действия, а 2 может быть допустимым значением параметра для параметра Id param. Поскольку запрос получил правильное определение маршрута в соответствии с его шаблоном url, он никогда не будет оцениваться по другим определениям маршрутов, определенным ниже первого.

Сначала определите все определённые определения маршрута и укажите generic-default как последний.

Или вы можете использовать маршрутизацию атрибутов для определения этого шаблона маршрута в контрольном контроллере. Чтобы включить маршрутизацию атрибутов, вы можете вызвать метод MapMvcAttributeRoutes в методе маршрута RouteConfig.cs . Вы по-прежнему сохраните определение маршрута по умолчанию.

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapMvcAttributeRoutes(); 

    routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{id}", 
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 

    ); 
} 

и в вашем TestController

[Route("Test/Edit/{id?}")] 
public ActionResult Edit(int? id) 
{ 
    //check id value and return something 
} 

Кроме того, нет никакого смысла в определении пользовательского маршрута, если он совпадает с общим определением маршрута по умолчанию. В вашем случае. Даже если вы не определяете настраиваемый маршрут, перейдет к методу Edit действия TestController, поскольку запрос соответствует определению маршрута по умолчанию.

Люди обычно используют эти определения пользовательских маршрутов для создания хороших шаблонов URL, как

определения
[Route("Product/{id}/{name}")] 
public ActionResult View(int id,string name) 
{ 
    //check id value and return something 
} 

Этого маршрут будет соответствовать запросу Product/34/seo-friendly-name. Взгляните на URL этого вопроса, и вы поймете, что я здесь объясняю.

2

Переключить маршруты в RoutesConfig.cs. Они должны идти от самого конкретного к общему.

Ваш маршрут по умолчанию ловит этот.

1

Пожалуйста, замените свой маршрут в RouteConfig, потому что порядок маршрутов действительно имеет значение.

Смежные вопросы