Rounting in asp mvc areas - issue with more areas

2019-05-29 23:11发布

问题:

Routing make me crazy thees days :( I have two areas: CityPage and Job On the city page I have a list of links that navigate to Job area. This is code for action and routing for CityPage:

public ActionResult Index(string city, string countryCode)
        {
            return View();
        }

In CityPageAreaRegistration.cs class:
context.MapRoute(
                null,
                "CityPage/{countryCode}/{city}",
                new { area = "CityPage", controller = "Home", action = "Index", city = "" }
            );

URL that I get here is fine

http://localhost/CityPage/UK/London

From CityPage index I can navigate to Jobs list (Job/Home/Index)

@Html.ActionLink("Jobs", "Index", "Home", new { area = "Job" }, null)

This is code from Job area:

public ActionResult Index()
        {
            return View();
        }
context.MapRoute(
                null,
                "{area}/{countryCode}/{city}/Job/{controller}/{action}",
                new { area = "Job", controller = "Home", action = "Index",
                      countryCode = "UK",
                      city = "London"
                }
            );

URL that I get here is still fine

http://localhost/CityPage/UK/London/Job

But on that page I have link to job details (Job/Home/Show)

@Html.ActionLink("Job Example", "Show", "Home", new { area = "Job", jobId = 8765 }, null)

And URL that I get is

http://localhost/CityPage/UK/London/Job/Home/Show?jobId=8765

I have tried to add routing like this

            context.MapRoute(
                "Jobs",
                "{area}/Job/{jobId}",
                new
                {
                    area = "Job",
                    controller = "Home",
                    action = "Index",
                    countryCode = "RS",
                    city = "Kragujevac",
                    jobId = ""
                }
            );

But it doesn't work. I don't know what am I doing wrong :( URL that I am trying to get is something like

http://localhost/CityPage/UK/London/Job/8765

I still learning about routing. But areas make me ...
I don't add any routing to Global.asax I think that I need to write routing code in areas routing.cs classes, am I right?

回答1:

It looks like you were pretty close.

I created a route like this:

context.MapRoute(
            "Job_Locator",
            "{countryCode}/{city}/Job/{jobId}",
            new
            {
                area = "Job",
                controller = "Home",
                action = "Show"
            }
        );

And then an actionlink like this:

@Html.ActionLink("Test", "Index", "Home", new { Area = "Job", countryCode = "UK", city = "London", jobId = 10 }, null)

Where the action is:

public ActionResult Index(string city, string countryCode, int jobId)
{
    return View();
}

Keep in mind that I created a new area called "Job" and I have a HomeController there with the Index action



回答2:

I've been following your craziness. I'd like to suggest you try something called T4MVC. It is available as a NuGet package, and I think is now part of MvcContrib.

I am a big fan of T4MVC. It makes routing URLs to action methods MUCH easier, and gets rid of a lot of magic strings.

Here is an example of a route definition in the "Common" area on our app:

context.MapRoutes(null,
    new[] { string.Empty, "features", "features/{version}" },
    new
    {
        area = MVC.Common.Name,
        controller = MVC.Common.Features.Name,
        action = MVC.Common.Features.ActionNames.ForPreview,
        version = "december-2011-preview-2",
    },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

Notice there are no magic strings for area, controller, or action names. All of this stuff is strongly-typed by T4MVC. The greatest part is this: look how we can generate a link to these pages:

@Html.ActionLink("December 2011 Preview 2 features", 
    MVC.Common.Features.ForPreview())
@Html.ActionLink("December 2011 Preview 1 features", 
    MVC.Common.Features.ForPreview("december-2011-preview-1"))

There are some ActionLink overloads that take an ActionResult parameter. T4MVC gives you a strongly-typed ActionResult method that you can use in this overload. Parameters passed to the method will map with your route definitions.

When I'm coding routes and action methods, I only worry that the name of the URL parameters in my route match the arguments to the action method they are mapped to. So here is the signature of the ForPreview method on FeaturesController:

public virtual ActionResult ForPreview(
    string version = "december-2011-preview-2")

This approach makes cross linking between areas a lot easier, give it a shot.

Update

Oops, the above route definition won't compile by default. I forgot I have this extension method in the project:

public static void MapRoutes(this AreaRegistrationContext context,
    string name, IEnumerable<string> urls, object defaults, 
    object constraints = null)
{
    foreach (var url in urls)
        context.MapRoute(name, url, defaults, constraints);
}