开发者

MVC 3 Route resolution question

I have the following 3 routes

  • student/available/classes/{id}
  • student/available/classes/{studentId}/{classTypeId}
  • student/available/classes/query/{q}

This is how I register the routes in my global.asax.cs file

//Student Checkin
routes.MapRoute("StudentAvailableClasses_GetAllForStudent",
            "student/available/classes/{id}",
            new {controller = "StudentCheckin", action = "GetById"});
routes.MapRoute("StudentAvailableClasses_GetClassForStudent",
   开发者_运维知识库         "student/available/classes/{studentId}/{classTypeId}",
            new { controller = "StudentCheckin", action = "GetByStudentAndClassType" });
routes.MapRoute("StudentAvailableClasses_Query",
            "student/available/classes/query/{q}",
            new { controller = "StudentCheckin", action = "Query" });

When I execute this url

student/available/classes/query/smith+john

MVC tries to run this route:

student/available/classes/{studentId}/{classTypeId}

If I reverse the order in which I register the Query route with the GetClassForStudent route, MVC resolves to the query route.

What is going on here, and how can I register these routes with MVC so that they all resolve correctly?

UPDATE

Wow, once again thank you to everyone here on stackoverflow! Based on everyone's responses, and in particular the answer by Beno, I now understand my issue, and was able to make it work!

From what I understand, I was not giving MVC enough information about the routes. It was matching the word 'query' into the {studentId} parameter. From Beno's answer I learned about parameter constraints. So now I am able to tell MVC to expect a Guid type in the {studentId} (and {customerId}) parameter.

Here is the code now.

    //Student Checkin
    routes.MapRoute("StudentAvailableClasses_GetAllForStudent",
                    "student/available/classes/{id}",
                    new {controller = "StudentCheckin", action = "GetById"},
                    new {id = new GuidConstraint()});
    routes.MapRoute("StudentAvailableClasses_GetClassForStudent",
                    "student/available/classes/{studentId}/{classTypeId}",
                    new {controller = "StudentCheckin", action = "GetByStudentAndClassType"},
                    new {studentId = new GuidConstraint(), classTypeId = new GuidConstraint()});
    routes.MapRoute("StudentAvailableClasses_Query",
                    "student/available/classes/query/{q}",
                    new { controller = "StudentCheckin", action = "Query" });

The class GuidConstraint I found from this stackoverflow question.

Thank you!


I would highly recommed running your routes through the Routing Debugger. It will show you exactly where your hangups are.

MVC 3 Route resolution question


What is going on here?

The URL, student/available/classes/query/smith+john is correctly picked up by the route student/available/classes/{studentId}/{classTypeId} since {studentID} can be anything, including 'query'. 'smith+john' is then picked up as the {classTypeId}

how can I register these routes with MVC so that they all resolve correctly?

You could add some validation to the {studentId} field. I don't know what your studentId is but if it's an 8 digit number:

routes.MapRoute("StudentAvailableClasses_GetClassForStudent",
       "student/available/classes/{studentId}/{classTypeId}",
       new { controller = "StudentCheckin", action = "GetByStudentAndClassType" }
       new { studentId = @"\d{8}" } );

OR

you could place the StudentAvailableClasses_Query route at the top so it gets matched before the other one

OR

a combination of both which is probably the best bet


Routes resolve in the order in which you register them. Always register more specific routes before more general routes.

To resolve your issue, move the "StudentAvailableClasses_Query" route to be the first one mapped.

counsellorben

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜