假设我有一个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样式控制器的最佳做法是什么?
答案 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"); }
同样 - 如果您信任表单数据,无论您使用哪种方法进行更新,都会出现同样的安全问题。