2011-01-31 100 views
0

我是ASP.Net MVC的新手。可能這個問題看起來很簡單,但我無法修復它。這裏的場景。我有一個基於城市的應用程序列表數據。因此,將URL看起來像這樣動態ASP.Net路由問題

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

在正常路由的第一部分(奈/孟買)在上述網址控制器,但在這裏我不希望這是一個控制器。相反,我想將單個控制器(LocationController)映射到這些URl。因爲以後的時間我可以添加任何數量的城市。

我很驚訝,有人可以幫我一把。

回答

2

試試這個:

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

我按照你的說法試過。但它不工作... – RameshVel

+0

@Ramesh:你是什麼意思,它不工作?你還在使用原始路線定義嗎?你有一個名爲'city'的字符串參數的控制器動作嗎?這絕對有效。你一定在做錯事。 –

+0

@Robert Koritnik,是的,我正在使用原來的定義一起...我正在尋找你的答案。我會改變,如果多數民衆贊成在這個問題... – RameshVel

0

你可以做到這一點通過增加硬編碼控制器名稱路線:

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 
) 

這將路由表格的所有請求「/孟買」來LocationController動作方法Index參數cityName設置爲「孟買」。它也將能夠使用第二條路線發送完整的控制器/操作規範。

+0

它不能正常工作...... – RameshVel

+0

這當然不是正確的路線,因爲它的工作原理是:「www.xxxxxx.in/location/index/mumbai」,這不是他想要的。 –

+0

@Robert Koritnik如果它是唯一定義的路線,它將起作用。當框架未提供時,該框架將替換默認值,並允許顯式的控制器/操作/參數URL。 –

1

我不確定不會有比這更容易的選項,但您可以試試這個 - 使用路由約束。基本上,您需要知道您擁有的城市列表,然後將路線限制爲僅匹配該列表中的條目。

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

還要確保上述路由的默認路由

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

路線約束可以如下

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()); 
    } 
} 

,然後把路線如下實施

另請注意,沒有控制器名稱可以是城市名稱。

試試看看。

+0

s,感謝您的好主意..其有趣的:) – RameshVel

+0

這可能更好地反轉路由排序並將控制器名稱約束放在默認路由上,因爲定義的控制器數量有限,並且城市最有可能是動態定義的數據庫。所以默認路由首先有約束,然後是位置路由。 –

+0

反轉也意味着不需要自定義約束類。您可以輕鬆使用內置的約束功能。 –

1

如果你所有的路由與這些城市比刪除默認路由,並與該路由定義代替它:

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

然後創建一個LocationController類:

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

如果您仍然需要你其他頁面的默認路由(控制器/動作/ ID)不只是城市那麼它可能更好地把約束你的默認路由,並定義它們是這樣的:

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" } 
); 

這將使其他控制器仍然工作和位置將工作一樣好。問題當然是如果有一個城市名稱與您的一個常規控制器的名稱相同。 :)但是你也可以控制/避免這種情況。