ASP.NET MVC routing without controller or action n

2019-09-18 16:38发布

问题:

My URL structure is like http://website.com/city-state/category e.g. /miami-fl/restaurants or /los-angeles-ca/bars. In order to send it to the correct controller, I have a class derived from RouteBase, which splits the request path and figures out the city, state and category. This is working fine for incoming URLs.

public class LegacyUrlRoute : RouteBase
{

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData routeData = new RouteData();
        routeData.RouteHandler = new MvcRouteHandler();

        string url = httpContext.Request.Path.ToLower(); //e.g. url = /los-angeles
        string[] path = url.TrimStart('/').Split('/'); //
        if (path.Length > 1)
        {
            string[] locale = path[0].Split('-');
            if (locale.Length > 1) //This is a city page, so send it to category controller
            {
                string stateName = locale[locale.Length - 1];
                string cityName = path[0].Replace(stateName, "").TrimEnd('-');

                routeData.Values.Add("controller", "Category");
                routeData.Values.Add("action", "City");
                routeData.Values.Add("categoryname", path[1]);
                routeData.Values.Add("city", cityName);
                routeData.Values.Add("state", stateName);
            }
        }
    }
}

However, when I try to use Html.ActionLink to create a link, it doesn't pick up from this class.

@Html.ActionLink("Restaurants in Miami", "Index", "Category", new {categoryname="Restaurants", state="FL", city="Miami"})

gives me a url of /category/index?categoryname=restaurants&state=fl&city=miami. How do I generate accurate links for my URL structure.

回答1:

If you want your outgoing URLs to function, you must implement GetVirtualPath, which converts a set of route values into a URL. It should typically be the mirror image of your GetRouteData method.

The simplest way to implement it would just be to make a data structure that maps your route values to URLs and then use it in both methods as in this example.