Readable Return Urls in your MVC Urls

Don't surrender your clean, readable url to a nasty returnUrl string; keep your MVC urls readable

Asp.Net MVC projects have a great routing resource available to them; this makes for very clean and human-readable urls:

http://website/Extensions/.doc,.pdf


A lot of these web applications will use a returnUrl somewhere in there, this is where the problem comes in: return urls tend to be ugly and unreadable if passed in the query. Let's say I am not deleting something and want to return to the page I was at before, if I simply use a returnTo, the url looks like this:

http://website/Delete/15?returnTo=http%3A%2F%2Fwebsite%2FExtensions%2F.doc%2C.pdf


The markup I used to get that was this:
<%= Html.ActionLink("Delete", "Delete", 
  new { Id = 15, returnTo = 
    ViewContext.HttpContext.Request.Url.ToString() })
%>
Yes, I know you won't hard-code your Id in there, but it's an example. That works just fine, and the user will probably not care, but I do... To go to all that trouble to get nice readable urls, then spit out something that looks this ugly is sacrilege, there has got to be a better way, and there is, and it is ridiculously simple.

set up your routes

In your global.asax.cs, I just need to add 'catch-all' parameter, and make it nice and readable:
routes.MapRoute(null, 
  "Delete/{Id}/ReturnTo/{*returnTo}", 
  new { controller = "Search", action = "Delete", 
    returnTo = "" },
  new { Id = @"\d+" }
);

What that {*returnTo} parameter does, is catch everything after '/ReturnTo/' in the url path (this excludes any querystring) - it is important to note that this also includes all of the slashes and does not convert anything into ugly '%2f' type notation.

update your markup

Now the exact same markup above outputs this nice url instead:

http://website/Delete/15/ReturnTo/
  http://website/Extensions/.doc,.pdf


Better, but still a bit more than we need, we can make it look better by changing the markup slightly:
<%= Html.ActionLink("Delete", "Delete", 
  new { Id = 15, 
    returnTo = ViewContext.HttpContext.Request.Url
      .LocalPath.ToString() })
%>

Adding in that '.LocalPath' now gives us this:

http://website/Delete/15/ReturnTo/Extensions/.doc,.pdf


A nice, very readable url.

return to the url

The rest is pretty trivial, just return to the url:
public RedirectResult Delete(int Id, string returnTo)
{
    // do your magic here, then:
    return Redirect("~/" + returnTo);
}
Comments are closed