url rewriting in mvc4 with razor engine

11,513

You must map this route before all the other route mappings (routes are evaluated in order):

routes.MapRoute(
  name: "Product", // any name meaningful for you is right
  url: "Product/{productName}",
   defaults: new { controller = "Product", action = "CategoryLevel" }
);

This route will catch all the URLS that look like this:

http://myserver/Product/X

whatever X is. If you do so, your action should look like this:

public ActionResult CategoryLevel(string productName)

NOTE: The parameter name must match the segment in the route mapping: productName

So, whenever the user types:

http://myserver/Product/Vitamins

the action CategoryLevel will be executed, and it will receive the productName parameter with the value "Vitamins"

The problem is that if you have an action List which you expect to be invoked like this

http://myserver/Product/List

the route will map it and will invoke the CategoryLevel action with the productName = "List"

To avoid this you can use this route:

routes.MapRoute(
  name: "Product", // any name meaningful for you is right
  url: "ViewProduct/{productName}",
   defaults: new { controller = "Product", action = "CategoryLevel" }
);

Which will be different from the others, and anything will work fine. The URLs specific for this method will look like this:

http://myserver/ViewProduct/TheProductName

and the other routes will work as expected.

By the way: you should have an specific action for the product, for example View, instead of CategoryLevel. So, the route and the action would look like this:

    routes.MapRoute(
        name: "ViewProduct", // any name meaningful for you is right
        url: "ViewProduct/{productName}",
        defaults: new { controller = "Product", action = "View" }
    );

The action, inside the product controller:

public ActionResult View(string productName)

The route is used both for mapping a user typed url to the corresponding action, and for generating URLs by using some of the MVC helpers, like Html.ActionLink or Url.Action. So, if you do something like this:

Url.Action('View', 'Product', new {productName = "Vitamins"} )

you'll get the expected, short URL:

http://myserver/ViewProduct/Vitamins

I.e. the route map it's a two-way map that can map URLs to actions and viceversa.

Share:
11,513
user3166404
Author by

user3166404

Updated on June 04, 2022

Comments

  • user3166404
    user3166404 almost 2 years

    I want to rewrite following url -

    http://localhost:99/Product/CategoryLevel?CategoryId=65&ProductName=Vitamins

    with

    http://localhost:99/Product/Vitamins,

    (or)

    http://localhost:99/Product/CategoryLevel/Vitamins

    (or)

    http://localhost:99/Vitamins

    (or) how to remove (or) hide the querystring from the url (that was shown to the users)?

    I tried using url rewrite module(iis) and asp.net routing and search for the solution in the internet,but i didn't find right solution for this,please suggest any solutions.

  • user3166404
    user3166404 over 10 years
    i used this code but the url is still same routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( name: "[clv]", url: "{controller}/{action}/{id}", defaults: new { controller = "Product", action = "CategoryLevel", id = UrlParameter.Optional } );@Devcon 2
  • Dieter B
    Dieter B over 10 years
    Did you also changed the action in your Controller?
  • user3166404
    user3166404 over 10 years
    yes, public ActionResult CategoryLevel(string ID) {-----------------}@Devcon 2
  • user3166404
    user3166404 over 10 years
    its working but still iam getting like this localhost:99/Product/Vitamins?CategoryId=65 but i dont want to display ?CategoryId=65 and i am not able to access the next level@JotaBe
  • JotaBe
    JotaBe over 10 years
    How are you getting that wrong URL? if you don't need that parameter, don't use it, and it will stop appearing in the url.
  • A Khudairy
    A Khudairy over 10 years
    @JotaBe this is nice. But what I don't like about it is, first with this approach if some one calls the original call '/Product/CategoryLevel?CategoryId=65&ProductName=Vitamins' it will not work. Also in case you have some other actions on that controller other than 'List' which you have suggested, you will end up writing a route for each one.
  • user3166404
    user3166404 over 10 years
    urls in my mvc4 mobile application:first level:localhost:99/Product/…, second level:localhost:99/Product/…, third level:localhost:99/Product/…
  • user3166404
    user3166404 over 10 years
    routeconfig is routes.MapRoute( name: "Product", // any name meaningful for you is right url: "Product/{productName}/", defaults: new { controller = "Product", action = "CategoryLevel" } ); routes.MapRoute( name: "Home", url: "{controller}/{action}", defaults: new { controller = "Home", action = "Index" } ); @JotaBe
  • user3166404
    user3166404 over 10 years
    when iam using above code,first level displayed ashttp://localhost:99/Product/Healthy%20Living?CategoryId=11‌​&ParentCategoryId=0 and second level is displayed as localhost:99/Product/… iam not able access the third level@JotaBe
  • user3166404
    user3166404 over 10 years
    actionis:public ActionResultCategoryLevel(stringproductName{stringProductNam‌​e=Request.QueryStrin‌​g["ProductName"];Vie‌​wBag.ProductName=Pro‌​ductName;intCategory‌​=Convert.ToInt32(Req‌​uest.QueryString["Ca‌​tegoryId"]); ViewBag.ParentCategoryId = Category; int ParentCategoryId = 0; if (Request.QueryString["ParentCategoryId"] != null) {ParentCategoryId=Convert.ToInt32(Request.QueryString["Paren‌​tCategoryId"]); }Product productInstance =newProduct();IList<CategoryInfo> categories = new List<CategoryInfo>();categories=productInstance.GetCategorie‌​s(Category,true); @JotaBe
  • user3166404
    user3166404 over 10 years
    if i don't use the parameter it will not redirect to the next page, <li><a href="@Url.Action("CategoryLevel", "Product", new { CategoryId = @item._categoryId, ParentCategoryId=@item._parentId, ProductName = @Html.Raw(item._categoryName) })">@Html.Raw(item._categoryName)</a></li>@JotaBe
  • JotaBe
    JotaBe over 10 years
    Please, edit your question... It's very difficult to view the code inside the comments :( There are solutions for all your old urls to start working again, but I need to see clearly the code that you've added to the comments. Improve your question and it'll be my pleasure to give you further help.
  • JotaBe
    JotaBe over 10 years
    Please, also explain why are you worried about people using the old url format.
  • Egli Becerra
    Egli Becerra over 3 years
    this question is specifically for MVC4 which is not core... its ok if you want to recommend latest approaches but in real work life sometimes we have legacy apps we need to maintain.