ASP.NET MVC Tought us many new things, it also helped us with our urls by making use of MVC Routing.
One particular example would be to view a users details: http://www.yourdomain.com/User/Detail/163. As you can see, search engines can clearly see that you are viewing a users's details. but we are missing one important thing here.
What is the person's name ?!?
Would it not make more sense to have the username as part of the url?
To have your username part of the url you have two options, possibly more, but i am going to explain to basic options:
1)http://www.yourdomain.com/User/Detail/Dusty-Roberts
To achieve this is fairly simple, as all you need to do is define your route appropriatly in your global.asax file, and you will be able to achieve the required result.
2)http://www.yourdomain.com/User/Detail/163/Dusty-Roberts
This is the route i will be focussing on, as this can be implemented after your site is already up and running, with minimal effort.
First we need to map an additional route in our global.asax file above our "default":
routes.MapRoute(
"Descriptive", // Route name
"{controller}/{action}/{id}/{description}", // URL with parameters
new { controller = "Home", action = "Dashboard", id = UrlParameter.Optional
, description = UrlParameter.Optional } // Parameter defaults
);
This will allow us to append any string after the id:
1)http://www.yourdomain.com/User/Detail/163/Dusty-Roberts
2)http://www.yourdomain.com/User/Detail/163/Some-Other-User
3)http://www.yourdomain.com/User/Detail/163/What-Ever-I-Want
You will notice that when ever i access one of those url's it will always go to /User/Detail/163, and because we are not doing anything with the string after /163/, it will be ignored.
Now all we need to do is create 3 helper functions so we can make this a little bit easer.
public static class HtmlHelperExtenstions
{
//Action Helper
public static string DescriptiveAction(this HtmlHelper htmlHelper, string actionName, string controllerName, string description, object routeValues)
{
UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
return urlHelper.Action(actionName, controllerName, routeValues) + "/" + description.CleanForUrl();
}
//ActionLink Helper
public static string DescriptiveActionLink(this HtmlHelper htmlHelper, string text, string actionName, string controllerName, string description, object routeValues)
{
return DescriptiveActionLink(htmlHelper, text, actionName, controllerName, description, routeValues, null);
}
//ActionLink Helper
public static string DescriptiveActionLink(this HtmlHelper htmlHelper, string text, string actionName, string controllerName, string description, object routeValues, object htmlAttributes)
{
UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
var tagBuilder = new TagBuilder("a");
tagBuilder.InnerHtml = text;
tagBuilder.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues) + "/" + description.CleanForUrl());
if (htmlAttributes != null)
tagBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
return tagBuilder.ToString();
}
//Some Regex to make cleanup the description
public static string CleanForUrl(this string text)
{
return Regex.Replace(text, @"[^a-z^A-Z^0-9^-]", "-").Replace(" ", "-");
}
}
How will this helpers render?
Default Url Helper
Input: Url.Action("Detail","User",new{id=193})
Output: /User/Detail/163
Extended Helper
Input: Html.DescriptiveAction("Detail","User", "Some Description Here",new{id=193})
Output: /User/Detail/163/Some-Description-Here
Default Action Link
Input: Html.ActionLink("User Details","Detail","User",new{id=193})
Output: href="/User/Detail/163"
Extended Action Link
Input: Html.DescriptiveActionLink("User Details","Detail","User", "Some Description Here",new{id=193})
Output: href="/User/Detail/163/Some-Description-Here"
All of this now makes your links just a little bit more SEO Friendly
Here is a link to the
Sample Application