1

I'm working on an ASP.NET MVC 3 app and it works fine when using the default routes. So I have urls similar to this, localhost:4457/Users/Details/5
I want to add a friendly slug to the url to make it localhost:4457/Users/Details/5/some-ones-name.
So I added a custom route and my routes now look like so

routes.MapRoute(
     "withslug",
     "{controller}/{action}/{id}/{slug}",
      new { controller = "Home", action = "Index", id = UrlParameter.Optional, slug = UrlParameter.Optional });

 routes.MapRoute(
     "Default",
     "{controller}/{action}/{id}",
      new { controller = "Home", action = "Index", id = UrlParameter.Optional });

On the view I have an action link like this

@Html.ActionLink(Model.Name,"Details","Users", new { id=Model.ID, slug="some-ones-name"},null)

I also have image links like this

<img src="../../Content/images/picture.jpg" alt="" height="42" width="37" />

The link works okay and when I click it follows correctly. The address reads localhost:4457/Users/Details/5/some-ones-name. The problem is all the images on the page are now broken and my javascript functions won't run.
If I remove the slug from the address and just leave the url as localhost:4457/Users/Details/5 everything works as expected.

If I add even a slash after the id, everything breaks again. The content loads as expected though, just the images and some javascript functions.

I don't understand what the problem is and any insight will be highly appreciated.

5 Answers 5

6

The slug is being treated as a directory. You would need to add an extra ../ to the image path for it to work when the url contains a slug. You should really avoid using relative paths like that on your website.

How to fix it so that it works on every page

You could change it to use a path that is relative to the site root like so:

<img src="/Content/images/picture.jpg" alt="" height="42" width="37" />

Or you could use a helper method that is available with asp.net mvc, it works like this. This method will auto-magically translate the path relative to the current url.

<img src="@Url.Content("~/Content/images/picture.jpg")" ... />

This will work with <script> and <link> tags as well as any other tag which references a url.

NOTE: I am using Razor syntax above, if you are using the web forms view engine the code would look like this.

<img src="<%: Url.Content("~/Content/images/picture.jpg") %>" ... />

Additional note, I feel dirty having just written the <% %> tags after having used razor for a few months.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I had mixed Url.Content and in other parts used ../../. I changed everything to Url.Content and it works like magic. Thank you very much :-)
I'm using Spark with custom bindings and defining a common script location. My syntax is <Script src="myscript.js" /> Could do the same thing for images. :) sparkviewengine.com/documentation/bindings
1

It might be easiest to just use absolute paths for your images and JavaScript e.g.

<img src="/Content/images/picture.jpg" alt="" />

That way, if you need to modify your URL routes again you won't have to worry about breaking any relative paths to images, CSS or JavaScript again.

The ResolveClientUrl method might come in useful for generating your absolute paths:

<img src="<%= ResolveClientUrl("~/Content/images/picture.jpg") %>" alt="" />

Comments

1

Don't use relative paths, if at all possible. Use this instead:

<img src="<%= Url.Content("~/Content/images/picture.jpg")%>" alt="" />

Comments

0

I'm not a routing expert yet, but I wonder if your problem is having two adjacent optional elements. How can the route engine distinguish between a route missing the {id} and one missing the {slug}? What about changing the route to something like {controller}/{action}/{id}-{slug}?

Comments

0

Just try to use:

<img src="../../../images/logo.png" />

And you can access images from all levels

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.