1

I am creating an ASP.NET MVC app. Currently my links look like:

/Campaign/Overview/996e19da-c5e6-e511-948f-005056822904

/Service/Offer/767619da-c5e6-e511-948f-005056e529a5

I would like them to look like:

/Campaign/Overview/996e19da-c5e6-e511-948f-005056822904/campain-user-friendly-text-taken-from-the-db

/Service/Offer/767619da-c5e6-e511-948f-005056e529a5/service-user-friendly-text-taken-from-the-db

  1. This means that when you access /Campaign/Overview/996e19da-c5e6-e511-948f-005056822904/ you should get 301 and be redirected to /Campaign/Overview/996e19da-c5e6-e511-948f-005056822904/campain-user-friendly-text-taken-from-the-db

  2. Also, when you post to /Campaign/Overview/996e19da-c5e6-e511-948f-005056822904/campain-user-friendly-text-taken-from-the-db and in the method you do return View(vm); it should keep that URL.

  3. And last, but not least when you use @Html.ActionLink("Click here", "Overview", "Campaign") I would like it to create the link with the user friendly text (which will be something else in case of campaign and service).

What is the easiest solution to what I want? I can think of things that I can do with routing and some htmlHelper extensions, but I feel like I am making it too complex and that I am reinventing the wheel. Am I?

A smilar question has been asked here: How do I create userfriendly urls like stackoverflow?, but it does not answer my question.

Community
  • 1
  • 1
Michal B.
  • 5,676
  • 6
  • 42
  • 70
  • 1
    Its referred to as a slug. Refer [this answer](http://stackoverflow.com/questions/30349412/how-to-implement-url-rewriting-similar-to-so/30363600#30363600) for one way to implement it. –  Mar 18 '16 at 10:14
  • I didn't know about the name. Thanks, I will for sure be able to find more info about it now. On the other hand, in the implementation provided under your link, I need to check for the slug in each method. This seems a bit repetitive, I would prefer to put it in one place. Any idea how this can be done best? I can think of an attribute decorating the method, but...again, maybe there is a good pattern and I am reinventing the wheel ;-) – Michal B. Mar 18 '16 at 10:29
  • If your only providing the ID, then you need to look up the relevant database table associated with the controller. I think the only way a `FilterAttribute` could work was if your controller name matched exactly your table name (or at least some convention so that your could match them up) and call some generic `GetSlug(Guid ID)` method. –  Mar 18 '16 at 10:37
  • Per controller I can define a type which is also used in IDBSet in my DbContext, so that would work. I could also build HtmlHelper template extension to get a slug for different types. And for the View I could make an override that would get the slug and put it in place. I think it all makes sense. Thanks a lot for help! If someone knows some package that does those things, so I do not have to implement it on my own, then please let me know :-) – Michal B. Mar 18 '16 at 10:44
  • 1
    Not tested, but if you using a Repository Pattern and DI to inject your context, and you have a BaseController with a property (say) `protected IRepository Repository`, then you would be able to use something like `string slug = filterContext.Controller.Repository.GetSlug(filterContext.ActionParameters["ID"]);` –  Mar 18 '16 at 11:03
  • 2
    Note that although you didn't mention it, you could remove that ugly GUID from the URL by storing the URLs in your persistent data storage and looking up the primary key via [data-driven routing](http://stackoverflow.com/questions/32565768/change-route-collection-of-mvc6-after-startup#32586837). – NightOwl888 Mar 18 '16 at 15:13
  • Very nice @NightOwl888, thanks! – Michal B. Mar 22 '16 at 11:56

0 Answers0