0

I'm currently a little new to Microsoft's MVC4 and I don't quite understand routing as well as I would like.

What I am trying to do is make my URLs more human readable. Currently I have URLs that look like this:

  • foo.com/UserProfile/Details/6
  • foo.com/UserExperience/Details/
  • foo.com/UserSpecificController/Edit/8

All of the user controllers are prefixed with "User" I was wondering if it was possible to change those URLs so they look like this:

  • foo.com/u/Profile/Details/6
  • foo.com/u/Experience/Details/
  • foo.com/u/SpecificController/Edit/8

My first attempt was with IIS:

<rewrite>
        <rules>
            <rule name="AddTrailingSlashRule1" stopProcessing="true">
                <match url="(.*[^/])$" />
                <conditions>
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                </conditions>
                <action type="Redirect" url="{R:1}/" />
            </rule>
            <rule name="Pretty User Redirect" enabled="false" stopProcessing="true">
                <match url="User(.*)/(.*)" />
                <action type="Redirect" url="u/{R:1}/{R:2}" />
                <conditions>
                </conditions>
            </rule>
            <rule name="User pretty URL Rewrite">
                <match url="u/(.*)/(.*)" />
                <action type="Rewrite" url="User{R:1}/{R:2}" />
            </rule>
        </rules>
    </rewrite>

This worked quite well except I would get /u/ on all of my links, everywhere...

For example: foo.com/Home/WhatWeDo/

would come out like: foo.com/u/Home/WhatWeDo/

This would then 404.

I am using the default routing configuration

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

And all of my links are drawn with @Html.ActionLink(...)

If anyone could shed some light on this, that would be greatly appreciated.

William
  • 75
  • 1
  • 1
  • 6

1 Answers1

0

Remove your custom IIS rewrite rules and insert this before your Default route

routes.MapRoute(
    name: "UserProfile",
    url: "u/Profile/{action}/{id}",
    defaults: new { controller = "Home", id = UrlParameter.Optional }
);

routes.MapRoute(
   name: "UserExperience",
   url: "u/Experience/{action}/{id}",
   defaults: new { controller = "Home", id = UrlParameter.Optional }
);

Edit: Areas

With Areas you group related controllers

Profile controller within a User area
/User/Profile/Details

Experience controller
/User/Experience/Details

Then just one custom rule for that area's RegisterArea to substitute the 'u' in your routes

context.MapRoute(
    "UsersRoute",
    "u/{controller}/{action}/{id}",
    new { Controller = "Home", action = "Index", id = UrlParameter.Optional },
    new string[] { "MyNamespace.MyProj.Areas.User.Controllers" }
);
Jasen
  • 14,030
  • 3
  • 51
  • 68
  • This seems a little in elegant, I would have to do this for each of my controllers? Is there a way of adding my own code/module that would rewrite the URLs how I want? – William Feb 09 '13 at 05:15
  • Perhaps you want Areas in your project. Then you'll change the controller class names and not worry about custom routing/rewriting. – Jasen Feb 09 '13 at 20:49