1110
1110

Reputation: 6829

How to control routing values

Maybe I don't understand real purpose of asp mvc routing.
I created an application and now I need to fix my url's a to be more understandable.
For example I have area Cities with controller Home and action Index.
So here I need url like: localhost/London but with current routing I get localhost/cityPage/Home.
My question is can I somehow pass parameter like city name and make URL like I want?
This is my current default routing in Global.asax

routes.MapRoute(
                "Default",
                "{area}/{controller}/{action}/{id}",
                new { area = "CityPage", controller = "Home", action = "Index", id = "" },
                new string[] { "MyProject.Areas.Cities.Controllers" }).DataTokens.Add("area", "Cities");

New routing:

routes.MapRoute(null,
                            "CityPage/{cityName}",
                            new
                            {
                                area = "CityPage",
                                controller = "Home",
                                action = "Index"
                            }
                        );

            routes.MapRoute(
                "Default",
                "{area}/{controller}/{action}/{id}",
                new { area = "CityPage", controller = "Home", action = "Index", id = "" },
                new string[] { "MyProject.WebUI.Areas.CityPage.Controllers" }).DataTokens.Add("area", "CityPage");

Example of link that I click

@Html.ActionLink("City London", "Index", "Home", new { cityName = "London" }, null)

Upvotes: 0

Views: 587

Answers (2)

danludwig
danludwig

Reputation: 47375

In order to route the URL localhost/London to the Index action on the HomeController of the Cities area, you need a route like this:

routes.MapRoute(null,
    "{id}",
    new 
    {
        area = "Cities", controller = "Home", action = "Index"
    }
);

Be sure this route is declared before the "Default" route in your CitiesAreaRegistration.cs class.

However if you have a lot of other routes in your application, adding a general route like this can play havoc with other routes in the app. I suggest adding a URL prefix to separate this route from others in your application:

routes.MapRoute(null,
    "cities/{id}",
    new 
    {
        area = "Cities", controller = "Home", action = "Index"
    }
);

This will make your URL look like localhost/cities/London. Is that acceptable?

Update 1

Unless you completely remove your "Default" route definition, you will actually have multiple INBOUND routes that map to this action. You would have localhost/cities/London, localhost/cityPage/Home, localhost/cityPage/Home/Index, and localhost/cityPage/Home/Index/London all resolving to that action. However when MVC chooses to generate an OUTBOUND route, it will choose the first one -- localhost/cities/London.

Update 2

If you want your route parameter to be cityName, you would do this:

routes.MapRoute(null,
    "cities/{cityName}",
    new 
    {
        area = "Cities", controller = "Home", action = "Index"
    }
);

However you would then have to change the Index action on your Cities area's HomeController to have this signature:

public ActionResult Index(string cityName)

By changing the argument from id to cityName, you are telling MVC to pass this URL paramter / route segment to the action method.

Update 3

Is the name of your area "Cities" or "CityPage"? From previous code it looked like the name of your area was Cities.

If it is CitiesPage, try this for your action method:

@Html.ActionLink("City London", "Index", "Home", 
    new { area = "CityPage", cityName = "London" })

Final Answer

I just reproduced this in an MVC3 project, and it is working as expected:

  1. Created a new area named "CityPage"
  2. Added a HomeController with an Index action to the CityPage area
  3. Added an Index view to the CityPage/Views/Home folder.

CityPageAreaRegistration.cs:

public class CityPageAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "CityPage";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(null,
            "CityPage/{cityName}",
            new { area = "CityPage", controller = "Home", action = "Index" }
        );

        //context.MapRoute(
        //    "CityPage_default",
        //    "CityPage/{controller}/{action}/{id}",
        //    new { action = "Index", id = UrlParameter.Optional }
        //);
    }
}

HomeController.cs:

public class HomeController : Controller
{
    //
    // GET: /CityPage/Home/

    public ActionResult Index(string cityName)
    {
        return View();
    }

}

Index.cshtml:

@{
    ViewBag.Title = "Index";
}
<h2>
    Index</h2>
@Html.ActionLink("City London", "Index", "Home", 
    new { area = "CityPage", cityName = "London" }, null)

Finally, here is the link generated by the action link:

<a href="/CityPage/London">City London</a>

Upvotes: 1

dotnetstep
dotnetstep

Reputation: 17485

yes you can do this way but you have to do following thing

  1. Make sure your route must register before generic route.
  2. Get Information about RouteConstraint

http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-a-route-constraint-cs http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-a-custom-route-constraint-cs

Just for example Try this way check your required url localhost/London

routes.MapRoute(
                "Default",
                "{id}",
                new { area = "CityPage", controller = "Home", action = "Index", id = "" },
                new string[] { "MyProject.Areas.Cities.Controllers" }).DataTokens.Add("area", "Cities");

Upvotes: 0

Related Questions