具有不同 Http 方法但参数相同的 RESTful 控制器
假设我有一个控制器来处理“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 风格控制器的最佳实践是什么?
Let's say I have a Controller that handles a CRUD scenario for a 'Home'. The Get would look something like this:
[HttpGet]
public ActionResult Index(int? homeId)
{
Home home = homeRepo.GetHome(homeId.Value);
return Json(home, JsonRequestBehavior.AllowGet);
}
So far so good. Then I add a post action for adding new ones.
[HttpPost]
public ActionResult Index(Home home)
{
//add the new home to the db
return Json(new { success = true });
}
Awesome. But when I use the same scheme to handle puts (updating an existing home)...
[HttpPut]
public ActionResult Index(Home home)
{
//update existing home in the db
return Json(new { success = true });
}
We run into a problem. The method signatures for Post and Put are identical, which of course C# doesn't like. I could try a few things, like adding bogus parameters to the signature, or changing the method names to directly reflect CRUD. Those are hacky or undesirable, though.
What is the best practice for going about preserving RESTful, CRUD style controllers here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是我所知道的最好的解决方案:
基本上,
ActionNameAttribute
是为了处理这些场景而创建的。This is the best solution that I know of:
Basically the
ActionNameAttribute
was created to deal with these scenarios.HttpPut 和 HttpDeletes 受到某些防火墙的限制,因此有时仅使用 HttpPost 和 HttpGet。如果传入了记录 ID(或其他一些条件),您就知道它是更新。当然 - 这是由您决定的,httpput 可能对您来说工作得很好,这只是一个警告,通常没什么大不了的。
无论使用哪种方法 - 请注意用户试图将虚假 ID 注入页面以强制更新他们无权访问的记录。在这种情况下,当我们在您的视图中渲染视图时,我通过在视图上散列 home.HomeId 来解决这个问题
:
在您的 HttpPost 或 HttpPut 方法中(以执行更新的为准)
同样,无论您使用哪种方法,都存在相同的安全问题如果您信任表单数据,请进行更新。
HttpPut and HttpDeletes are restricted by some firewalls so at times simply HttpPost and HttpGet are used. If a record ID is passed in (or some other criteria) you know its an update. Granted - this is for you to determine, httpput may work just fine for you, this is just a warning on it, it usually isn't a big deal.
Either method used - beware of users trying to inject false IDs into the page in order to forcing updates of records they don't have access to. I get around this issue by hashing in this case home.HomeId on the view when we render it
in your view:
in your HttpPost or HttpPut method (whichever is doing the update)
Again - this same security issue exists no matter which method you use to do your update if you are trusting form data.