开发者

Dynamic ASP.Net Routing problem

开发者 https://www.devze.com 2023-02-08 03:13 出处:网络
I am new to ASP.Net MVC. May be this question looks simple, but i couldn\'t fix it. Here 开发者_开发知识库the scenario. I have an application listing data based on city. So the url will be looking lik

I am new to ASP.Net MVC. May be this question looks simple, but i couldn't fix it. Here 开发者_开发知识库the scenario. I have an application listing data based on city. So the url will be looking like this

        www.xxxxxx.in/chennai
        www.xxxxxx.in/mumbai
        www.xxxxxx.in/delhi

In normal routing the first part (chennai/mumbai) is controller in the above url, But here i dont want this to be a controller. instead i want to map the single controller (LocationController) to these URl's. Because later time i can add any number of city.

I am struck here, can someone help me out.


Try this:

  routes.MapRoute(
            "CityRoute",                                              // Route name
            "{city}",                           // URL with parameters
            new { controller = "Location", action = "Index", city = "" }  // Parameter defaults
        );


I am not sure there won't be easier option than this, but you can try this - using route constraint. Basically, you need to know the list of cities you have and then constrain the route to match only entries in that list.

The route constraint can be implemented as follows

public class CityConstraint : IRouteConstraint
{
    public static IList<string> CityNames = (Container.ResolveShared<ICityService>()).GetCities();

    bool _IsCity;
    public CityConstraint(bool IsCity)
    {
        _IsCity = IsCity;            
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (_IsCity)
            return CityNames.Contains(values[parameterName].ToString().ToLower());
        else
            return !CityNames.Contains(values[parameterName].ToString().ToLower());
    }
}

And then put the route as follows:

routes.MapRoute("Location", "{cityName}", new { controller = "LocationController", action = "Index" }, new { cityName = new CityConstraint(true) });

Also make sure the above route is listed before the default route

routes.MapRoute("Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional
            );

Also note that, no controller name can be a city name.

Try this and see.


If all your routing is related to these cities than remove default route and replace it with this route definition:

routes.MapRoute(
    "Default",
    "{city}",
    new { controller = "Location", action = "Index", city = "Mumbai" }
);

Then create a LocationController class:

public class LocationController : Controller
{
    public ActionResult Index(string city)
    {
        // do whatever needed; "city" param has the city specified in URL route
    }
}

If you still need your default route (controller/action/id) for other pages not just cities then it's probably better to put a constraint on your default route and define them like this:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new { controller = "Home|...|..." } // put all controllers here except "Location"
);
routes.MapRoute(
    "Location",
    "{city}",
    new { controller = "Location", action = "Index", city = "Mumbai" }
);

This will make other controllers still working and location will work just as well. The problem is of course if there's a city name that's the same as a name of one of your regular controllers. :) But you can control/avoid that as well.


You can do that by adding a route that hardcodes the controller name:

routes.MapRoute(
  "location", // Route name
  "{cityName}", // URL with parameters
  new { controller = "location", action = "index" } // Parameter defaults
);

routes.MapRoute(
  "Location", // Route name
  "{controller}/{action}/{cityName}", // URL with parameters
   new { controller = "Location", action = "index"} // Parameter defaults
)

This will route all requests of the form "/mumbai" to LocationController action method Index with parameter cityName set to "mumbai". It will also be able to route full controller/action spec using the second route.

0

精彩评论

暂无评论...
验证码 换一张
取 消