使用不同Http方法的RESTful控制器,但相同的参数

时间:2011-02-08 22:50:44

标签: asp.net-mvc rest crud

假设我有一个Controller来处理'Home'的CRUD场景。 Get会看起来像这样:

    [HttpGet]
    public ActionResult Index(int? homeId)
    {
        Home home = homeRepo.GetHome(homeId.Value);

        return Json(home, JsonRequestBehavior.AllowGet);
    }

到目前为止一切顺利。然后我添加了一个用于添加新帖子的帖子。

    [HttpPost]
    public ActionResult Index(Home home)
    {
        //add the new home to the db

        return Json(new { success = true });
    }

真棒。但是当我使用相同的方案来处理put(更新现有的家庭)时......

    [HttpPut]
    public ActionResult Index(Home home)
    {
        //update existing home in the db

        return Json(new { success = true });
    }

我们遇到了问题。 Post和Put的方法签名是相同的,当然C#不喜欢。我可以尝试一些方法,比如在签名中添加伪参数,或者更改方法名称以直接反映CRUD。然而,这些都是黑客或不受欢迎的。

在这里开始保留RESTful,CRUD样式控制器的最佳做法是什么?

2 个答案:

答案 0 :(得分:12)

这是我所知道的最佳解决方案:

[HttpPut]
[ActionName("Index")]
public ActionResult IndexPut(Home home) 
{
     ...
}

基本上ActionNameAttribute是为了处理这些情景而创建的。

答案 1 :(得分:0)

HttpPut和HttpDeletes受到某些防火墙的限制,因此有时只使用HttpPost和HttpGet。如果传入记录ID(或其他一些标准),您就知道它有更新。当然 - 这是供您确定的,httpput可能对您有用,这只是一个警告,它通常不是什么大问题。

使用任何一种方法 - 小心用户尝试向页面中注入错误ID,以强制更新他们无权访问的记录。我在这种情况下通过哈希来解决这个问题。在我们呈现它时,我在视图上进行哈希

ViewData["IdCheck"] = Encryption.ComputeHash(home.HomeId.ToString());
在您看来

    <%: Html.Hidden("IdCheck", ViewData["IdCheck"]) %>

在您的HttpPost或HttpPut方法中(以更新者为准)

 if (Encryption.ComputeHash(home.HomeId.ToString()) != (string)Request.Form["IdCheck"])
 {
       throw new Exception("Hashes do not match");
}

同样 - 如果您信任表单数据,无论您使用哪种方法进行更新,都会出现同样的安全问题。