Search code examples
c#ajaxasp.net-mvcroutesrouteconfig

Route configuration looking for an id in my URL


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.


Solution

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