0

How do I correct my routing to fix an issue with ajax .load()

I modified my route to my spacecontroller so that it looks like this

routes.MapRoute(
            name: "SpaceCleanRoute",
            url: "Space/{id}",
            defaults: new { controller = "Space", action = "Index" }
        );

so that I have a cleaner route and when a user wants to see a space the URL will look like this

www.mysite/space/12345

the problem I'm having now is when my JS file calls a .load() like this, , where spaceoverview is my action

$("#partialPageContainer").load('/Space/SpaceOverview', function (response, status, xhr) {
        alert("Load was performed.");
    });

I get an error saying

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

So I have to put an id after the url like this, which is not what I want, or doesn't seem right to me

How can I fix this or is this just how the routing works? I'm kinda new to mvc routing with ASP.Net

$("#partialPageContainer").load('/Space/SpaceOverview/1', function (response, status, xhr) {
        alert("Load was performed.");
    });

UPDATED - I guess for now I'll just use '/space/actionname/1' to connect to each action, until I can find a better solution.

chuckd
  • 13,460
  • 29
  • 152
  • 331
  • Did you try to make id and nullable first, just to make sure it is hitting right route? – Faisal Dec 09 '16 at 18:55
  • I'm not sure what you mean. Can you provide an example? If I use the url '/space/spaceoverview/{id}' then it works, where id is any number. If I don't use id then an exception is thrown and the action is never entered into. This just doesn't seem right and I would like to know ifthere is a way to make it so I don't have to enter in an id for a load? – chuckd Dec 09 '16 at 19:26
  • `'/Space/SpaceOverview` means you calling the `Index()` method of `SpaceController` (as defined by your route) and you passing the text "SpaceOverview" to the `int id` parameter (which of course fails and `id` is `null` - hence the exception). If your wanting to hit the `SpaceOverview()` method, then you need to remove that route definition, or create specific routes for each method before the `SpaceCleanRoute` route, or add a constraint to ensure the 2nd segment is an `int` –  Dec 10 '16 at 02:22

2 Answers2

2

You can use parameter constraints to filter out string values for the id parameter.

routes.MapRoute(
    name: "SpaceCleanRoute",
    url: "Space/{id}",
    defaults: new { controller = "Space", action = "Index" }
    constraints: new { id = @"\d+" }
);

Then you need to have your default route set up to handle things that don't match that constraint:

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

The first route will catch your

/Space/12345

example, because 12345 matches the @"\d+" pattern, however the second route will handle your

/Space/SpaceOverview

example, because SpaceOverview does not.

You can find more information and examples of route constraints here: https://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-a-route-constraint-cs

edit: I believe you can also use one of the built in routing constraints (which might work better, because technically a value could match the @"\d+" pattern but still not be a valid int), like this:

routes.MapRoute(
    name: "SpaceCleanRoute",
    url: "Space/{id}",
    defaults: new { controller = "Space", action = "Index" }
    constraints: new { id = new System.Web.Http.Routing.Constraints.IntRouteConstraint()}
);
Redit0
  • 370
  • 1
  • 14
0

If you want to send action parameter try this:

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