1

I'm kind of new to MVC. I have a controller called PostItemsController in an area called CaseManagers with an action method called GetByUmi(int caseNumber):

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

The routing configuration looks like this (not my work):

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 = "" }
    );

When I try to call this method with the URL http://localhost:[portnumber]/CaseManagers/PostItems/ViewByUmi/1234 I get the following exception:

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

I don't intend the ID parameter to be optional and I don't understand why MVC can't find the ID.

Can anyone tell me what I need to do?

EDIT:

Phil Haack's route tester is telling me that the following route is being mapped:

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

But it is being mapped AFTER another route CaseManagers/{controller}/{action}/{id}. But this route isn't anywhere in the Global.asax file (take a look, it's reproduced in full above).

Any idea what's going on?

5
  • You don't seem to have a casemanagers route defined ... Commented Jul 18, 2011 at 12:32
  • You say that the controller you want is in the CaseManager area? Are these the routes for that Area, or are these the globals routes? Commented Jul 18, 2011 at 12:34
  • You don't have any route matching your controller action. You should call this method directly via http://localhost:[portnumber]/CaseManagers/PostItems/ViewByUmi?umi=1234 (assuming that you have a CaseManagers area and a PostItemsController with a ViewByUmi action) or add a custom route. Commented Jul 18, 2011 at 12:43
  • @Mike Richards - these are the global routes. Commented Jul 18, 2011 at 12:54
  • @Paulo Moretti - tried that (i.e. changed URL to give name to parameter) but still same error. Commented Jul 18, 2011 at 12:56

3 Answers 3

1

Method parameters in ASP.NET MVC match up 1-1 with route parameters. Since you have no routes that take in a route value named umi, no route will catch what you're trying to do.

You have one of two choices:

  1. If you want the default route to handle that action, then change:

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

to:

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

However, if you want to keep umi(because it has contextual meaning that makes that code easier to follow), then you want to add a route to explicitly deal with it:

//UMI route
  routes.MapRoute(
  "umi",
  "/case/postitems/view/{umi}",
  new { area = "CaseManager", controller = "PostItems", action = "ViewByUmi", umi = "" }
);
Sign up to request clarification or add additional context in comments.

4 Comments

I tried the latter suggestion (adding the routing as specified) but still got the same error.
@David where did you add the route to? It needs to be before your 'default' route, or before another route that has the same URL structure. Phil Haack's RouteDebugger helps with this. haacked.com/archive/2008/03/13/url-routing-debugger.aspx
the new route is the first of my routes.MapRoute() calls.
Thanks George. Using the route debugger helped me solve this problem.
1

Turns out that Global.asax isn't the only place that routing happens. Each of the areas in this application has its AreaRegistration class. I added a new route to the top of this class to produce the following:

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 }
      );
    }
  }

The routing debugger now tells me this is getting matched first. Now I just need to work out why I've got an error telling the the resource cannot be found...

1 Comment

Ah, just a typo. I've got the default action name in the routing as 'GetByUmi', but the action's name is 'ViewByUmi'.
0

You don't have a route for CaseManagers/PostItems/ViewByUmi/1234 and it would appear that it is taking ViewByUmi and try to convert it to an System.Int32 because it is falling into the Default route. If you create a Route for your CaseManagers you should no longer have this problem.

Use Phil Haacks' Route Debugger to help you out :o)

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

3 Comments

This is a good answer, but I don't know how to create the route!
@David: Please see amendment including a Route.
@David: Sorry, I missed the CaseManagers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.