Stackoverflow style URL (customising outgoing URL)
Asked Answered
K

2

10

If I navigate to the following stackoverflow URL http://stackoverflow.com/questions/15532493 it is automatically appended with the title of the question like so:

https://mcmap.net/q/1168261/-mvc-custom-route-gives-404

That is, I can type the URL into my browser without the question title and it is appended automatically.

How would I go about achieving the same result in my application? (Note: I am aware that the question title doesn't affect the page that is rendered).

I have a controller called Users with an action method called Details. I have the following route defined:

routes.MapRoute("UserRoute",
    "Users/{*domain}",
     new { controller = "User", action = "Details" },
     new { action = "^Details$" });

As this is an intranet application the user is authenticated against their Windows account. I want to append the domain and user name to the URL.

If I generate the URL in the view like so:

@Html.ActionLink("Model.UserName", "Details", "User", new { domain = Model.Identity.Replace("\\", "/") })

I get a URL that look like this:

Domain/Users/ACME/jsmith

However, if the user navigates to the URL Domain/Users/ by using the browsers navigation bar it matches the route and the user is taken to the user details page. I would like to append the ACME/jsmith/ onto the URL in this case.

The research I have done so far indicates I might have to implement a custom route object by deriving from RouteBase and implementing the GetRouteData and GetVirtualPath methods but I do not know where to start with this (the msdn documentaiton is very thin).

So what I would like to know is:

  1. Is there a way of achieving this without implementing a custom route?
  2. If not, does anyone know of any good resources to get me started implementing a custom route?
  3. If a custom route implementation is required, how does it get at the information which presumably has to be loaded from the database? Is it OK to have a service make database calls in a route (which seems wrong to me) or can the information be passed to the route by the MVC framework?
Krucik answered 9/4, 2013 at 14:9 Comment(3)
#25759Naturalistic
@Soner Gönül - The linked question shows how-to-generate-strings-like-this which is not what I'm asking. I want to append the values to the url if the user enters just the Domain/Users/ bit in the browsers navigation bar.Krucik
It's not actually a duplicate since he is not asking HOW to generate the title string, but instead how to always redirect to a page where the title is in the URL even if the user got there just by entering the idUndersurface
U
3

It's actually pretty simple. Since the title is just there for SEO reasons you do not need to get to the actual question, so the Question controller (in SO case) will load the correct question based on the id (in the URL) and redirect the user with a 301 status code.

You can see this behavior with any web inspector

enter image description here

Undersurface answered 9/4, 2013 at 18:25 Comment(3)
Thanks, this is what I was going to try originally but it didn't feel right; guess I should learn to trust my instincts. I will test later to see if I can get this working. Am I correct in thinking this means the database will be hit 2 times?Krucik
Yes, but SO probably has some sort of caching or optmization in place so they can translate IDs to question titles and not hit the database twice with the full load.Undersurface
Works perfectly. Thank you very much. I'm a bit uncomfortable with the double hit on the database but I'm only pulling a small amount of information down and I don't expect anywhere near the traffic of Stackoverflow so I will cross that bridge and implement a caching policy if it becomes a problem.Krucik
N
1

You could do it client-side with Javascript:

history.pushState({}, /* Title Here */, /* URL Here */ );

Only downside is not all browsers support it.

Nunnally answered 9/4, 2013 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.