Wai Yan Hein
Wai Yan Hein

Reputation: 14771

Cannot encode route data value in URL rewriting in RouteConfig in ASP.Net MVC

I am developing an ASP.NET MVC Website. In my website, I am doing url rewriting in RouteConfig for better SEO. But I am having a problem with that. The problem is with Encoding URL route data value.

I rewrite a URL in RouteConfig like this:

routes.MapRoute(
               "",
               "places/category/{categoryName}/{category}",
               new { controller = "Item", action = "List", categoryName = "", category = 0 },
               new string[] { "AyarDirectory.Web.Controllers" }
               );

In my HTML, I created an anchor link like this:

<a href="@Url.Content("~/places/category/" + HttpUtility.UrlEncode(category.Name) + "/" + category.Id)">
Content
</a>

When I click on it, if the name does not contain characters like "+","%" after encoded, it is always showing 404. It the value does not contains space and /(so no characters like % and +) after encoded, it is working fine.

I catch value in action like:

HttpUtility.UrlDecode(value)

Why it is not working? How can I encode route data value? Even if the value contains space, if I don't encode value, it is working fine. The result URL will be something like this with space.

http://localhost:50489/places/guest house/4

So if I use without encoding value, it the value contains "/", it will be error. Why is that happening and how can I encode URL route data value?

Upvotes: 1

Views: 730

Answers (1)

NightOwl888
NightOwl888

Reputation: 56849

You should never hard-code URLs into your application. The whole point of using routing (rather than URL rewriting) is that it allows you to store all of your URL creation logic in one place (namely the route table).

Not only does routing ensure you have maintainable URLs, it also provides a mechanism that will URL encode the segments automatically. Rather than using Url.Content, you should use Html.ActionLink, Html.RouteLink, or Url.Action to build your URLs using MVC.

Html.ActionLink

@Html.ActionLink("Content", "List", "Item", 
    new { categoryName = category.Name, id = category.Id }, null)

Html.RouteLink

If you need to call a specific route by name, you can use Html.RouteLink.

@Html.RouteLink("Content", "TheRoute", new { 
    controller = "Item", 
    action = "List", 
    categoryName = category.Name, 
    id = category.Id })

But, you need to give your route a name.

routes.MapRoute(
           "TheRoute",
           "places/category/{categoryName}/{category}",
           new { controller = "Item", action = "List", categoryName = "", category = 0 },
           new string[] { "AyarDirectory.Web.Controllers" }
           );

NOTE: You can also use RouteLink without supplying a route name. In this case it works similar to ActionLink. This can be useful if you already have a RouteValueDictionary instance with route values in it and just want to build a hyperlink to those route values.

Url.Action

If you need to add HTML inside of the anchor tag, you can use Url.Action.

<a href="@Url.Action("List", "Item", new { categoryName = category.Name, id = category.Id })">
    HTML Content Here...
</a>

Upvotes: 1

Related Questions