Routing and Controller Actions - Optional Data
I created a route in ASP.net MVC application that looks like this:
routes.MapRoute(
"ArticleRoute",
"{year}/{month}/{day}/{articleId}/{displayName}",
new { controller = "Article", action = "Details" }
);
I want a route that will be like a blog post article.
Example: http://www.foobar.com/2010/01/01/123456789/the-name-of-the-article开发者_如何学C
In my Details controller action I want to do a permanent redirect if the year, month, date and display name are not correct. I want to know the best way to write the Details() controller method.
The only field that is truly required is the articleId. If I have the article Id then the database will have what the article date and name are.
I really want to know how the controller method should look like. Do I pass in all of the values to the method or use RouteData to get them?
public ActionResult Details(int articleId, string displayName)
{
var article = */SNIP*/;
int articleYear = RouteData.Values["year"];
// etc.
DateTime articleDate = new DateTime(articleYear, articleMonth, articleDay);
string realDisplayName = article.Name.ToSeoString();
if( displayName != realDisplayName || article.Date != articleDate)
// permanent redirect to the actual article
return View();
}
OR
public ActionResult(int year, int month, int day, int articleId, string displayName)
{
var article = /*SNIP*/;
DateTime articleDate = new DateTime(year, month, day);
string realDisplayName = article.Name.ToSeoString();
if( displayName != realDisplayName || article.Date != articleDate )
// permanent redirect to the actual article
return View();
}
I think both technically work, but which is the better way?
Also: if there are any other flaws in what I am doing feel free to point them out.
I prefer RESTFul url s to query strings because they are clear, can be easily read by users and seo friendly.
In your case if you really want the url as .../2010/01/01/123456789/the-name-of-the-article the second method is the better one.
But I think there's no need to use the data/month if you are using the article id in the url.
Applications like wordpress use the /year/month/title format because if you just give the title of the article only it takes more time to query the database. But with the year and month you can speed up the db querying since you can narrow down the results and then do the title search on that result set.
I think you should use a route like .../123456789/the-name-of-the-article
See the url of this question it is Routing and Controller Actions - Optional Data in here the question title is used only for the seo purposes.
If you want the design to be pure restful then the url should be .../articles/the-name-of-the-article
I create urls like this as there are many ways to optimize the db querying (like hashing) and I LOVE pure REST.
In the case of the first example, what's the point of passing anything in if you are going to use RouteData.Values to get some values?
Also, is the var article = ... a placeholder for now until you hook up the database lookup?
From the client side, it wouldn't matter, because the URL wouldn't be any different.
On the server side, the second example looks cleaner in the code, because you don't have the lookup of RouteData.Values.
Query strings are much better than REST URLs. Routes are from early days of HTTP but was passed over for query strings for many web sites because parameters depend on route construction. Also, routes are not good for encrypting parameters when you need to.
Passing everything in is better because your parameters are strongly typed and the RouteData.Values collection is not. You are also able to cast the RouteData.Values items but that is extra code you don't have to do. This is another example of ASP.NET MVC doing code for you so you have less control if you want to do something different. Web Forms are more transparent for what the framework is actually doing, while MVC is smoke and mirrors.
精彩评论