我有一个架构,我可以配置很多对象。我想要的URL示例如下:
/configuration/building/add
/configuration/building/edit/1
/configuration/group/add
/configuration/group/edit/1
我有一个配置控制器,但我如何拦截或处理building/add
和building/edit/1
等...如果是AddBuilding
我只需添加一个AddBuilding()
功能,类似地,我如何让它适用于configuration/building/edit/
答案 0 :(得分:2)
以下是您可以为第一个做的事情 - 打开您网站的Global.asax.cs文件并将其放在RegisterRoutes
之前标准MVC捕获-all route(使用路由"{controller}/{action}/{id}"
的路由):
routes.MapRoute("AddBuilding", "configuration/building/add",
new { controller = "Configuration", action = "AddBuilding" });
其他的将是相同的,但不同的名称(第一个参数)和操作,请检查编辑路线,但包括{id}
路径占位符和路由参数(但不是可选的 - 与MVC默认路由不同):
routes.MapRoute("EditBuilding", "configuration/building/edit/{id}",
new { controller = "Configuration", action = "EditBuilding" });
让id
离开路线默认值,我们需要它。我假设这一点,因为我猜测网址/Building/Edit
没有逻辑映射到任何内容。
作为辅助节点 - 包含您网址中的动词并不真正符合REST方法,但您并不是第一个做的事情它有很长的路要走(我也将自己包含在内)。也就是说 - 试图保持这种状态通常会让您的生活变得更轻松,因为您会发现您的控制器会更清洁,您的路线表也会更清洁,并且您网站的网址空间会更小,等级更明显。最后一点是 - 方便用于在开发时缩放网站,但更重要的是它对搜索引擎优化至关重要。
所以(我已经对这段代码进行了大量评论,希望足以提供一些知识!):
public class ConfigurationController{
////HTTP GET /Buildings
/// DISPLAYS BUILDINGS
public ActionResult Buildings(){
//get model and return view that shows all buildings with perhaps a
//partial in that for creating a new one (or you can use another action)
//The HTML form on that view will POST to the URL handled by the method below.
}
////HTTP POST /Buildings
/// CREATES A NEW BUILDING
//use ActionName here to make this and the method above accessible through
//the same URL
[ActionName("Buildings")]
[HttpPost]
public ActionResult CreateBuilding(BuildingModel model){
//validate the model, create the object and return the same
//view as the Buildings() method above (after re-loading all the
//buildings. Or, you can issue a redirect, effectively transferring
//control back to the method above.
}
////HTTP GET /Configuration/Building/id
///DISPLAYS A BUILDING
public ActionResult Building(int id){
//get building and return view, which also contains Edit functionality
}
////HTTP POST /Configuration/Building/id
///EDITS A BUILDING
[HttpPost]
public ActionResult Building(int id, BuildingModel model){
//very similar to the CreateBuilding method - and again you might
//either simply return a building view at the end, or redirect
//to the method above.
//Note that we don't need [ActionName] here because this and the
//get method can have the same method names, because they are overloads
//i.e. since they have different method signatures we can call them the same
//thing in code.
}
}
我已经离开了小组,以保持简短,希望你能够从那里看到如何做到这一点。
有了这个,我们在Global.asax.cs中最多只需要两条路线 - 尽管我认为顺序很重要:
//handles both GET and POST to this URL, i.e. our view & edit operations
routes.MapRoute("IndividualBuilding", "/configuration/buildings/{id}",
new { controller = "Configuration", action = "Building" });
routes.MapRoute("Buildings", "/configuration/buildings",
new { controller = "Configuration", action = "Buildings" });
现在我们正在使用HTTP动词来表示我们打算对特定请求做些什么,而且我们的网址已经变得更加“符合逻辑”。
另一个重构
如果你想成为一个聪明的人。你可以把建筑物和团体分成两条路线
//handles both GET and POST to this URL, i.e. our view & edit operations
routes.MapRoute("Individual", "/configuration/{controller}/{id}",
new { controller = "Configuration", action = "List" });
//again, handles GET and POST
routes.MapRoute("Collection", "/configuration/{controller}",
new { controller = "Configuration", action = "Single" });
现在你按照我上面的说明执行建筑物和群组控制器,但用Buildings
和ActionName
替换List
(记住第二种方法的Building
属性) Single
。
最后要考虑的是因为默认的MVC路线:
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Default", action="Home", id = UrlParameter.Optional });
例如,您的两个控制器仍然可以通过/Buildings/Single/1
或/Groups
进行路由。这是一个小问题(欺骗内容不是很好的搜索引擎优化),但它可以是人们用来嗅探你网站的东西。
如果你绝对想要阻止这种其他网址格式;你可以取出默认路线,这意味着你必须明确地路由可能已经有效的其他东西(不是很大的问题)。
或者你可以使用一个让它变得更难的小技巧:使用明确的[ActionName]
属性,在路由名称中使用不允许通过IIS的字符 - 例如":Single"
或":List"
,然后相应地从几个代码块调整我们的两条路线。
答案 1 :(得分:0)
另一种方法是创建一个配置MVC area
,然后在controller
中建立一个建筑物和组Area
。
答案 2 :(得分:0)
你可以通过ASP.NET MVC 5中的属性路由来做到这一点。
// eg: /reviews
[Route(“reviews”)]
public ActionResult Index() { … }
// eg: /reviews/5
[Route(“reviews/{reviewId}”)]
public ActionResult Show(int reviewId) { … }
// eg: /reviews/5/edit
[Route(“reviews/{reviewId}/edit”)]
public ActionResult Edit(int reviewId) { … }
您也可以为同一控制器添加多条路线。有关详细信息,请查看here