代码之家  ›  专栏  ›  技术社区  ›  RoLYroLLs

属性正在修复两个名为id的参数

  •  2
  • RoLYroLLs  · 技术社区  · 8 年前

    所以我有一个使用默认值的项目 Route 属于

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
    

    我刚遇到7年前描述的情况 MVC Pro Tip: Don't use the "id" URL parameter in your routes .

    他们的解决方案非常好,但现在,我不想更改整个站点。我希望能解决我的问题 Attribute Routing .

    然而,我似乎不能让这个工作,我收到一个 404 Error 页。(如果上面的链接不起作用,我将在这里详细描述代码)。

    细节

    在我的项目中我使用 ViewModels . 这个 ViewModel (非常简单)定义为:

    public class Foo {
        public int Id { get; set; }
        ...
    }
    

    我的 BarController 如下:

    public ActionResult Create(string id) {
        if (string.IsNullOrWhiteSpace(id)) {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ...
    }
    
    [HttpPost]
    public ActionResult Create(string id, Foo viewModel) {
        if (string.IsNullOrWhiteSpace(id)) {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ...
    }
    

    误差

    当我导航到 /Bar/Create/abc123 ,我看我的表格很好。但是,当我提交表格时, Model.IsValid false . 看着 Watch 窗口 this.ModelState 对象,我找到了要说的错误消息

    值“abc123”对于ID无效。

    我想那是因为模型绑定器试图绑定 abc123 Id 视图模型 它有一个 int 作为 身份证件 属性。

    我试过的

    以下是迄今为止我在 Controller :

    [Route("Bar/Create/{aid}", Name = "FooBarRouteName")]
    public ActionResult Create(string aid) {
        if (string.IsNullOrWhiteSpace(aid)) {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ...
    }
    
    [HttpPost]
    public ActionResult Create(string aid, Foo viewModel) {
        if (string.IsNullOrWhiteSpace(aid)) {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ...
    }
    

    现在的问题是当我导航到 /bar/创建/abc123 ,我得到一个 404错误 页,甚至无法尝试提交表单。

    有人能指点我正确的方向吗?或者找出我做错了什么?谢谢!

    2 回复  |  直到 8 年前
        1
  •  2
  •   Nkosi    8 年前

    首先确保在基于约定的路由之前启用属性路由,以避免路由冲突。

    //Attribute routing
    routes.MapMvcAttributeRoutes();
    
    //Convention-based routing
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
    

    您在Post操作中缺少路线。

    如果使用属性路由,则必须修饰控制器上的所有操作

    [HttpGet]
    [Route("Bar/Create/{aid}", Name = "FooBarRouteName")] // GET Bar/Create/abc123
    public ActionResult Create(string aid) {
        if (string.IsNullOrWhiteSpace(aid)) {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ...
    }
    
    [HttpPost]
    [Route("Bar/Create/{aid}")] // POST Bar/Create/abc123
    public ActionResult Create(string aid, Foo viewModel) {
        if (string.IsNullOrWhiteSpace(aid)) {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ...
    }
    
        2
  •  2
  •   Christian Gollhardt    8 年前

    转储问题:您是否在 RouteConfig ?

    routes.MapMvcAttributeRoutes(); // should be the first call
    

    另外,请确保在注册默认路由之前正在调用上面的。这是因为当路由器解析路由时,第一个配置首先匹配。

    此外,您还需要确保在global.asax中具有正确的顺序,以防使用以下区域:

    RouteConfig.RegisterRoutes(RouteTable.Routes); //needs to be first
    AreaRegistration.RegisterAllAreas();
    

    AS answered by Nkosi 您还应该添加 RouteAttribute 你的另一个动作和装饰你的获得动作 HttpGetAttribute .