Question

I would like my MVC Urls to be like so:

http://www.site.com/project/id/projectname

Example:

http://www.site.com/project/5/new-website

My controller is:

public ActionResult Details(int id, string projectname)

Any my actionlink is:

@Html.ActionLink("click here", "Details", "Project", new { id = project.ProjectID, projectname = project.ProjectName })

And my route is:

routes.MapRoute(
    "Project",
    "project/{id}/{projectname}",
    new { controller = "Project", action = "Details", id = "", projectname = "" }
    );

Surely the system has enough information there, to know that project name will be part of the Url, so it should UrlEncode the link and thus replace spaces with hyphens? But it doesn't, and so spaces become %20

I'm not sure where I customise this? Do I override the Html.ActionLink? Storing a "URL-ready" version of the name in the database on every edit - seems like a such a waste, when it should be done automatically, on the fly. And I don't want to have to call a "FriendlyURL" function every time I use an Html.ActionLink - again, it should be dealt with automatically.

Was it helpful?

Solution

Changing a space character to %20 is a result of URL encoding. When you URL encode a space character, it does not get converted to a hyphen. If it did, then what do you think a hyphen would get converted to when URL encoded?

As @RK911 points out, what you want to do is create a slug.

There are a few ways to do this:

1.) Restrict your projectname data to disallow spaces, and only allow hyphens (using perhaps a validation on it during data entry).

2.) Store the slug separately in your database, something like projectslug.

3.) Create an extension method that will do this "on the fly" for you.

Here is an example of #3 using the link that @RK911 referenced:

public static class SlugExtensions
{
    public static string AsSlug(this string phrase) 
    { 
        string str = phrase.RemoveAccent().ToLower(); 
        // invalid chars           
        str = Regex.Replace(str, @"[^a-z0-9\s-]", ""); 
        // convert multiple spaces into one space   
        str = Regex.Replace(str, @"\s+", " ").Trim(); 
        // cut and trim 
        str = str.Substring(0, str.Length <= 45 ? str.Length : 45).Trim();   
        str = Regex.Replace(str, @"\s", "-"); // hyphens   
        return str; 
    } 

    private static string RemoveAccent(this string txt) 
    { 
        byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(txt); 
        return System.Text.Encoding.ASCII.GetString(bytes); 
    }
}

@Html.ActionLink("click here", "Details", "Project",
    new { id = project.ProjectID,
    projectname = project.ProjectName.AsSlug() })
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top