asp.net mvc - null参数异常 - 可能是路由问题?

时间:2011-07-18 12:28:51

标签: asp.net-mvc routing

我对MVC不熟悉。我在名为CaseManagers的区域中有一个名为PostItemsController的控制器,其中有一个名为GetByUmi(int caseNumber)的操作方法:

[HttpGet]
    public ViewResult ViewByUmi(int umi)
    {
      //implementation omitted
    }

路由配置看起来像这样(不是我的工作):

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
      //ignore route for ico files
      routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?../Images/MauriceFavicon.ico(/.*)?" });
      routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?Images/MauriceFavicon.ico(/.*)?" });
      routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?Content/Images/MauriceFavicon.ico(/.*)?" });
      routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?/favicon.ico(/.*)?" });

      //ignore javascript files routing
      routes.IgnoreRoute("{file}.js");

      //ignore routing for files ending .doc
      routes.IgnoreRoute("{resource}.doc");

      routes.MapRoute(
          "CaseManagers", // Route name         
          "CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters         
          new { controller = "PostItems" } // Parameter defaults         
);

      //InvoicesLookUp route
      routes.MapRoute(
         "InvoicesLookUpShortDefault", // Route name
         "InvoicesLookUp/{action}/{id}", // URL with parameters
         new { controller = "InvoicesLookUp", action = "Index", area = "Home", id = UrlParameter.Optional } // Parameter defaults
         ,
      null,
      new[] { "MooseMvc.Areas.Accounts.Controllers" } // Parameter defaults
      ).DataTokens.Add("area", "Accounts");


      //Invoices route
      routes.MapRoute(
         "InvoicesShortDefault", // Route name
         "Invoices/{action}/{id}", // URL with parameters
         new { controller = "Invoices", action = "Index", area = "Accounts", id = UrlParameter.Optional } // Parameter defaults
         ,
      null,
      new[] { "MooseMvc.Areas.Accounts.Controllers" } // Parameter defaults
  ).DataTokens.Add("area", "Accounts");




      //administrating route
      routes.MapRoute(
         "AdministratorShortDefault", // Route name
         "Administrator/{action}/{id}", // URL with parameters
         new { controller = "Administrator", action = "Index", area = "Administrator", id = UrlParameter.Optional } // Parameter defaults
     );

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

      //add root route route
      routes.MapRoute(
      "Root",
      "",
      new { controller = "Home", action = "Index", id = "" }
    );

当我尝试使用URL http://localhost:[portnumber]/CaseManagers/PostItems/ViewByUmi/1234调用此方法时,我收到以下异常:

The parameters dictionary contains a null entry for parameter 'umi' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ViewResult ViewByUmi(Int32)' in 'MooseMvc.Areas.CaseManagers.Controllers.PostItemsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters

我不打算将ID参数作为可选参数,我不明白为什么MVC找不到ID。

谁能告诉我我需要做什么?

编辑:

菲尔·哈克的路线测试员告诉我正在映射以下路线:

routes.MapRoute(
          "CaseManagers", // Route name         
          "CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters         
          new { controller = "PostItems" } // Parameter defaults         
);

但它正在另一条路线CaseManagers/{controller}/{action}/{id}之后进行映射。但是这条路线不在Global.asax文件中的任何地方(看看,它在上面全部转载)。

知道发生了什么事吗?

3 个答案:

答案 0 :(得分:1)

ASP.NET MVC中的方法参数与路由参数匹配1-1。由于您没有接收名为umi的路由值的路由,因此没有路由可以捕获您尝试执行的操作。

您有以下两种选择之一:

  1. 如果您希望默认路由处理该操作,请更改:
  2. public ViewResult ViewByUmi(int umi) { //implementation omitted }

    到:

    public ViewResult ViewByUmi(int id)
    { 
        //implementation omitted
    }
    

    但是,如果你想保留umi(因为它具有使代码更容易理解的上下文含义),那么你想添加一个明确处理它的路由:

    //UMI route
      routes.MapRoute(
      "umi",
      "/case/postitems/view/{umi}",
      new { area = "CaseManager", controller = "PostItems", action = "ViewByUmi", umi = "" }
    );
    

答案 1 :(得分:1)

事实证明,Global.asax不是路由发生的唯一地方。此应用程序中的每个区域都有其AreaRegistration类。我在这个类的顶部添加了一个新路由来生成以下内容:

public class CaseManagersAreaRegistration : AreaRegistration
  {
    public override string AreaName
    {
      get
      {
        return "CaseManagers";
      }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
      context.MapRoute(
          "PostItems", // Route name         
          "CaseManagers/PostItems/ViewByUmi/{umi}", // URL with parameters         
          new { area = "CaseManagers", controller = "PostItems", action = "GetByUmi", umi = "{umi}" } // Parameter defaults         
);
      context.MapRoute(
          "CaseManagers_default",
          "CaseManagers/{controller}/{action}/{id}",
          new { action = "Index", id = UrlParameter.Optional }
      );
    }
  }

路由调试器现在告诉我这首先匹配。现在我只需要弄清楚为什么我有一个错误告诉无法找到资源......

答案 2 :(得分:0)

您没有CaseManagers/PostItems/ViewByUmi/1234的路线,看起来它正在使用ViewByUmi并尝试将其转换为System.Int32,因为它落入{{1}路线。如果您为Default创建Route,则不应再出现此问题。

使用Phil Haacks'Route Debugger来帮助你:o)

CaseManagers