这是您可以为第一个执行的操作 - 打开您站点的 Global.asax.cs 文件并将其放在RegisterRoutes
标准MVC 包罗万象的路线(使用该路线的路线"{controller}/{action}/{id}"
)之前:
routes.MapRoute("AddBuilding", "configuration/building/add",
new { controller = "Configuration", action = "AddBuilding" });
其他的将是相同的,但不同的名称(第一个参数)和操作,whislt 编辑路由但将包括{id}
路由占位符和路由参数(但不是可选的 - 与 MVC 默认路由不同):
routes.MapRoute("EditBuilding", "configuration/building/edit/{id}",
new { controller = "Configuration", action = "EditBuilding" });
通过保留id
关闭路由默认值,我们将其设为必需。我假设这一点,因为我猜 Url/Building/Edit
在逻辑上没有映射到任何东西。
作为一个侧面节点- 在你的 url 中包含动词并不真正符合 REST 方法,但是你并不是第一个这样做的人(我也包括在内)。也就是说 - 尝试保持它通常会让你的生活更轻松,因为你会发现你的控制器会更干净,你的路由表也会更干净,并且你的网站的 URL 空间会更小,层次更明显。最后一点是 -在开发时缩放网站很方便,但更重要的是它对 SEO 至关重要。
所以(我已经对这段代码进行了大量评论,希望足以提供一些知识!):
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 动词来表示我们打算对特定请求执行的操作,并且我们的 URL 变得更加“合乎逻辑”。
另一个重构
如果您想变得“聪明”,您可以将建筑物和团体归为两条路线
//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
例如路由。这是一个小问题(欺骗内容不是很好的 SEO),但它可能是人们可以用来嗅探您的网站的东西。
如果您绝对想阻止这种其他 url 格式;您可以取出默认路由,这意味着您必须明确路由其他可能已经工作的东西(不是一个大问题)。
或者你可以使用一个小技巧,让它变得更加困难:使用[ActionName]
路由名称中不允许通过 IIS 的字符的显式属性 - 例如":Single"
or ":List"
,然后从几个代码块中相应地调整我们的两条路由。