MVC routing problem - trying to pick up the remainder after a hyphen in the route
I created the following route:
routes.MapRoute(
"Notes 1", // Route name
"{book}-{id}", // URL with parameters
new { controller = "Notes", action = "Note", id = UrlParameter.Optional }
);
Using this URL and the MVC route checker开发者_JAVA百科:
http://127.0.0.1:81/java-abcd-efg
id < efg
book < java-abcd
controller < Notes
action < Note
What I expected was that book would contain "java" and id would contain "abcd-efg". Can someone explain what's wrong and why this isn't the case.
Thanks
The problem is that you didn't tell MVC to expect more than one dash; so it grabbed what it found and tried to parse it that way.
Well, that just sucks for us.
If you know that your route will always be:
{book}-{name}-{perhapsMoreName-{maybeEvenMore}
Then we can handle that, but it's going to take work on the server side to parse that.
Believe me, it'd be much easier just to use slashes. If someone comes to you and complains about SEO, ask them to show you the exact place where it matters (And somehow why slashes don't work as well). I'm not saying they're wrong, but there's a lot of, "I think it works this way with SEO" and that gets annoying, fast.
I'm going to provide you with two solutions. Solution 1 would be the way I would handle it (and fight for) and solution 2 would be the solution to your particular problem with your current scheme for handling (and I've dealt with solution 2 in practice, and at best it is very icky).
Solution 1
Set up your routes similar to how Stack Overflow sets up theirs. This would allow your SEO guy to have his hallowed SEO, and you would get what you want: No ulcers.
Your URLs would change to look like:
http://example.com/books/id/book-type-name
routes.MapRoute("bookRoute",
"books/{id}/{*bookName}",
new { controller = "Notes", action = Show, id = "", bookName = "" }
);
Then, you can use the bookName for display, but not actually use it to get any code. Just change your Show
method to retrieve items by their Id.
Solution 2
This solution uses a ActionFilter to intercept the requests and parse out what's what. It's an icky solution, but it should work.
I wrote an answer that showed this solution for another question. It is applicable here as well, just change the search type to query the database based on what's in the URL. Also, the route will have to go at the bottom of your routes, otherwise it'll catch that first. All the standard disclaimers apply: Use parameretized queries, or an ORM that parameteretizes them for you.
It looks like the routing engine is evaluating from the right hand end first. I must say that your route design is not great. Basically having the same character to split parts of the route and also within a single part of the route is a big no-no. Can you change the hyphen for something else? I'd do it like this:
routes.MapRoute(
"Notes 1", // Route name
"{book}/{id}", // URL with parameters
new { controller = "Notes", action = "Note", id = UrlParameter.Optional }
);
which would yield this (can still keep hyphen within id):
http://127.0.0.1:81/java/abcd-efg
id < abcd-efg
book < java
controller < Notes
action < Note
精彩评论