6

I think I already asked this but the solution didn't really made sense. Anyway, I have ActionLinks on my views like this:

foreach( var item in Model){
<%: Html.ActionLink(item.Name, "Details", new {id = item.Id}) %>
}

now, when it goes to my Action Details obviously this will be the url

/MyThings/Details/{id}

I was wondering if it's possible to show the name of that item instead of the id Using a slug? or modifying the global asax like so:

/MyThings/Details/CarKeys

The thing is the names need to be unique, is there a way I can modify the global asax to show the name instead of the id?

Any advice is much appreciated!

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
gdubs
  • 2,724
  • 9
  • 55
  • 102

2 Answers2

8

If this is solely for SEO purposes, just include both the ID and the Name. The name will be part of the URL but not used by your application. Just add another route that uses the template: {controller}/{action}/{id}/{name}

You'll also want to transform your name to make sure that it has only valid characters for urls. There are tons of articles about this on the net and it's pretty simple. Here's an example: http://chrismckee.co.uk/creating-url-slugs-permalinks-in-csharp/

Malevolence
  • 1,857
  • 12
  • 9
  • well, it's more for better user experience, take rottentomatoes.com's example, if i click on a link >> http://www.rottentomatoes.com/m/the_ides_of_march/ it'll direct me to that record at the m controller. i was thinking they probably used that title as a key on the record? no? and thanks for the link btw! – gdubs Oct 21 '11 at 17:39
6

Sure, you just have to change your routing rules. Look in your Global.asax.cs file, or in your area registration file, for something like this:

routes.MapRoute(..., "{controller}/{action}/{id}", ...);

... and change it to something like this:

routes.MapRoute(..., "{controller}/{action}/{name}", ...);

Then have your action take the name instead of the ID:

Html.ActionLink(item.Name, "Details", new {item.Name})
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • yes, but this will need to change the queries wonce it gets to the controller correct? so from public ActionResult Details (int id) to public ActionResult Deatils (string name). I was kind of trying to avoid that, but if there isn't any option then i gues that's the way to go? – gdubs Oct 21 '11 at 15:42
  • Depends. Is the `{id}` parameter of your controller expecting a name? if so then just `new { id = item.Name }` – Buildstarted Oct 21 '11 at 15:50
  • @gdubs: Yeah, if you're going to identify stuff by its name, you'll obviously need to use a different query than if you're identifying it by its ID. There are some advanced binding tricks you can use to get around this, but I'd say you should keep it simple. If you want the convenience of the ID, but also want to include the name to make it look nice, just include both like Malevolence points out. – StriplingWarrior Oct 21 '11 at 17:05
  • that's a good idea, but was wondering on how i can do it the same as some sites, eg.rottentomatoes, where the movie title can be used to identify the record. maybe use it as a key? – gdubs Oct 21 '11 at 17:42
  • 1
    @gdubs: Exactly. As you said in your question, the names need to be unique. Rotten Tomatoes creates a unique key string for each film in their database (e.g. "footloose-2010"), and they use this key in the URLs instead of a numeric key. – StriplingWarrior Oct 21 '11 at 17:56
  • awesome, i just needed some kind of confirmation. as a follow up question tho, do you know of a good way on how to maintain the uniqueness of that key since it won't be an incrementing idea that is indexed already? – gdubs Oct 21 '11 at 18:02
  • 1
    From the database side, you can simply put a UNIQUE constraint on that field. From the UI, you'll probably want to require users to enter a key and have validation code check that the key isn't already in use before the item can be saved. You'll probably want to make the key read-only once the item is saved so that URLs won't change. – StriplingWarrior Oct 21 '11 at 18:45
  • is there a data annotation for read only? unique? i'm doing ef code first so i'm doing all attributes on mvc. – gdubs Oct 21 '11 at 20:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/4450/discussion-between-striplingwarrior-and-gdubs) – StriplingWarrior Oct 21 '11 at 21:14