具有不同 Http 方法但参数相同的 RESTful 控制器

发布于 2024-10-16 06:07:56 字数 847 浏览 4 评论 0原文

假设我有一个控制器来处理“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

才能让你更想念 2024-10-23 06:07:56

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

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

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

This is the best solution that I know of:

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

Basically the ActionNameAttribute was created to deal with these scenarios.

哆兒滾 2024-10-23 06:07:56

HttpPut 和 HttpDeletes 受到某些防火墙的限制,因此有时仅使用 HttpPost 和 HttpGet。如果传入了记录 ID(或其他一些条件),您就知道它是更新。当然 - 这是由您决定的,httpput 可能对您来说工作得很好,这只是一个警告,通常没什么大不了的。

无论使用哪种方法 - 请注意用户试图将虚假 ID 注入页面以强制更新他们无权访问的记录。在这种情况下,当我们在您的视图中渲染视图时,我通过在视图上散列 home.HomeId 来解决这个问题

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");
}

同样,无论您使用哪种方法,都存在相同的安全问题如果您信任表单数据,请进行更新。

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

ViewData["IdCheck"] = Encryption.ComputeHash(home.HomeId.ToString());

in your view:

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

in your HttpPost or HttpPut method (whichever is doing the update)

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

Again - this same security issue exists no matter which method you use to do your update if you are trusting form data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文