views:

54

answers:

2

I am reading in a number of strings which have /'es through them, the most common example being dates/numbers like 05/06, 07/08, etc.

I am using ASP.NET MVC2 and generating links off of these strings read out of DB, which therein lies the problem.

Obviously a link to:

www.mysite.com/yearperiod/05/06/detail

will not work the same as a link to

www.mysite.com/yearperiod/2005/detail

What is a good solution to this problem? My first thought is to convert every / to a - but then I run into the problem/overhead of having to keep track of which ones were converted, so that when writing back to the DB I don't inadvertantly switch a valid - to a / (if that makes sense)

edit: come to think of it, I wouldn't know how to keep track of each converted / ... hmmmm.....

edit1: Given this string: "2001/2 - Fruit"

var encodedLinkText = HttpContext.Current.Server.UrlEncode(linkText); //result is "2001%2f2+-+Fruit"

but then if I call that linkhelper from my view the rendered link comes out as : view source: <li><a href="2001%2f2+-+Fruit">2001/2 - Fruit</a></li> rendered link: http://localhost:XXXX/Period/2001/2+-+Fruit

while I need it as:

http://localhost:XXXX/Period/2001%2f2+-+Fruit

edit2: The browser (testing in chrome) is automatically converting the %2f to a / . What now?

edit3: uh oh... looks like IE behaves properly (as required)... hmmm...

  • IE displays the link properly (encoded) and after clicking it remains encoded.
  • Firefox displays the link decoded and after clicking is encoded.
  • Chrome displays link decoded and after clicking is decoded.
+1  A: 

Why not use Server.UrlEncode. You can UrlEncode all of your string.

string strDatePeriod = Server.UrlEncode("05/06");

To convert it back to its original string, you'll just have to use the Server.UrlDecode

string origStr = Server.UrlDecode(strDatePeriod);
rob waminal
Can I only use that code in the view? I'm trying to use it in my Pagelink helper class. Which namespace should be imported for `Server.` I thought it was `System.Web`
baron
you can just call it directly via `HttpContext.Current.Server.UrlEncode` and `HttpContext.Current.Server.UrlDecode` from the namespace `System.Web`
rob waminal
Please see my edits, the `/` is the problem, the `Server.UrlEncode` seems to be working but when it is rendered the slash is converted back ?
baron
+1  A: 

If your entity in your database is outputting the string '05/06' that entity must also have some sort of unique identifier, such as a primary key integer. Couldn't you include that as part of the URL so your above example becomes:

www.mysite.com/yearperiod/123/05-06/detail

Then you can convert your slashes to dashes to your hearts content without worrying about converting them back, because the actual database look-up is performed in the ID number (the '123' part) and not the date string.

If you look at StackOverflow's URLs they do something similar:

stackoverflow.com/questions/3648634/dealing-with-es-in-links

3648634 is the database ID for this question which is used to perform the look-up, the 'dealing-with-es-in-links' part is merely there for user friendly descriptive URLs and Search Engine Optimisation.

Here's a ToFriendlyUrl() method that can generate these nice looking, SO style, URLs without having to resort to URL Encoding which can make URLs look ugly:

public static class UrlEncoder 
{ 
    public static string ToFriendlyUrl (this UrlHelper helper, 
        string urlToEncode) 
    { 
        urlToEncode = (urlToEncode ?? "").Trim().ToLower(); 

        StringBuilder url = new StringBuilder(); 

        foreach (char ch in urlToEncode) 
        { 
            switch (ch) 
            { 
                case ' ': 
                    url.Append('-'); 
                    break; 
                case '&': 
                    url.Append("and"); 
                    break; 
                case '\'': 
                    break; 
                default: 
                    if ((ch >= '0' && ch <= '9') || 
                        (ch >= 'a' && ch <= 'z')) 
                    { 
                        url.Append(ch); 
                    } 
                    else 
                    { 
                        url.Append('-'); 
                    } 
                    break; 
            } 
        } 

        return url.ToString(); 
    } 
}

You can tweak the code to deal with other special characters such as &ampersands& , but you should get the general idea. You can use in your view like so:

<%= Url.ToFriendlyUrl(item.Title) %>

So in a nutshell, don't relly on UrlEncoding, but use a FriendlyUrl utility like the one above and include the database ID for the actual database look-up.

I've written a blog post in this subject her http://www.dominicpettifer.co.uk/Blog/34/asp-net-mvc-and-clean-seo-friendly-urls

Sunday Ironfoot
Wow, this is a much better solution...Can't believe I didn't think about using that instead, seems so obvious now! The converting back was what I was worried about, but relying on the id will be better and then I can do whatever I want to the url without worrying about 'uniqueness'. Thanks for your answer!
baron