MVC路由...如何设置我的控制器来处理/配置/构建/添加

时间:2012-07-27 12:57:34

标签: c# asp.net-mvc-3 razor asp.net-mvc-routing

我有一个架构,我可以配置很多对象。我想要的URL示例如下:

/configuration/building/add
/configuration/building/edit/1
/configuration/group/add
/configuration/group/edit/1

我有一个配置控制器,但我如何拦截或处理building/addbuilding/edit/1等...如果是AddBuilding我只需添加一个AddBuilding()功能,类似地,我如何让它适用于configuration/building/edit/

3 个答案:

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

现在你按照我上面的说明执行建筑物和群组控制器,但用BuildingsActionName替换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