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.
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
精彩评论