MVC3 REST路由和Http动词

one*_*mer 10 c# rest asp.net-mvc routing http

作为我之前的一个问题的结果,我发现了两种在MVC3中处理REST路由的方法.

这是一个后续问题,我试图了解这两种方法之间的事实差异/细微差别.如果可能的话,我正在寻找权威的答案.

方法1:单一路由,在控制器操作上具有操作名称+ Http谓词属性

  1. Global.asax使用指定action参数注册单个路由.

    public override void RegisterArea(AreaRegistrationContext context)
    {
        // actions should handle: GET, POST, PUT, DELETE
        context.MapRoute("Api-SinglePost", "api/posts/{id}", 
            new { controller = "Posts", action = "SinglePost" });
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将两者ActionNameHttpVerb属性应用于控制器操作

    [HttpGet]
    [ActionName("SinglePost")]
    public JsonResult Get(string id)
    {
        return Json(_service.Get(id));
    }
    [HttpDelete]
    [ActionName("SinglePost")]
    public JsonResult Delete(string id)
    {
        return Json(_service.Delete(id));
    }
    [HttpPost]
    [ActionName("SinglePost")]
    public JsonResult Create(Post post)
    {
        return Json(_service.Save(post));
    }
    [HttpPut]
    [ActionName("SinglePost")]
    public JsonResult Update(Post post)
    {
        return Json(_service.Update(post););
    }
    
    Run Code Online (Sandbox Code Playgroud)

方法2:唯一路由+动词约束,在控制器动作上具有Http动词属性

  1. 注册独特的路线Global.asaxHttpMethodContraint

    var postsUrl = "api/posts";
    
    routes.MapRoute("posts-get", postsUrl + "/{id}", 
        new { controller = "Posts", action = "Get",
        new { httpMethod = new HttpMethodConstraint("GET") });
    
    routes.MapRoute("posts-create", postsUrl, 
        new { controller = "Posts", action = "Create",
        new { httpMethod = new HttpMethodConstraint("POST") });
    
    routes.MapRoute("posts-update", postsUrl, 
        new { controller = "Posts", action = "Update",
        new { httpMethod = new HttpMethodConstraint("PUT") });
    
    routes.MapRoute("posts-delete", postsUrl + "/{id}", 
        new { controller = "Posts", action = "Delete",
        new { httpMethod = new HttpMethodConstraint("DELETE") });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在Controller Actions上仅使用Http Verb属性

    [HttpGet]
    public JsonResult Get(string id)
    {
        return Json(_service.Get(id));
    }
    [HttpDelete]
    public JsonResult Delete(string id)
    {
        return Json(_service.Delete(id));
    }
    [HttpPost]
    public JsonResult Create(Post post)
    {
        return Json(_service.Save(post));
    }
    [HttpPut]
    public JsonResult Update(Post post)
    {
        return Json(_service.Update(post););
    }
    
    Run Code Online (Sandbox Code Playgroud)

这两种方法都让我拥有唯一的命名控制器操作方法,并允许与动词绑定的RESTful路由...... 但是限制路由与使用代理操作名称本质上有什么不同?

Jim*_*sse 0

我不知道您是否会找到权威的答案,但我会提出我的意见,正如您从我的观点中可以看出的那样,我的意见很重要;-)。我的纯粹主义者认为第一个选项更纯粹,但是我的经验是,像 Url.Action() 这样的辅助方法有时会在用这种方法解决正确的路线时遇到麻烦,我已经采用了第二种方法,因为它实际上只具有内部影响,因为 API 对于消费者来说看起来是相同的。