【问题标题】:Can I have multiple POST actions for an ApiController?我可以对 ApiController 进行多个 POST 操作吗?
【发布时间】:2012-07-31 17:52:57
【问题描述】:

场景:

User 类有几组属性:passwordaddresspreferenceroles

我们需要不同的 Ajax 调用来更新 (1) 用户密码、(2) 用户配置文件、(3) 用户所在的角色。

所有教程和示例仅显示一个 POST 操作来更新整个 User 类。我的问题是我们如何才能只更新部分课程。

例如,在更新用户密码时,我们会:

  1. 显示一个文本框以从用户输入中收集新密码。
  2. 进行 Ajax 调用,仅将新密码与 userId(如:{id=3, newPassword=xxxxx})一起发布到 WebAPI POST 操作。
  3. 该操作只会更新用户的密码。

一种解决方案:(最容易想到的)

  1. 使用 userId 调用 GET 操作以检索用户的所有数据
  2. 使用从 Web 用户输入中获得的值更新用户数据中的密码
  3. 使用更新的数据调用POST 操作,其中包含用户类中的所有属性。
  4. POST 操作将更新整个数据,而无需知道仅更改了密码。

好处:ApiController 只需要一个POST 操作。

缺点:我们要 Ajax 两次。

那么,我们有可能在一个ApiController 中拥有多个POST 操作吗?例如,PostPassword(userId, password)PostProfile(userId, profile)PostRoles(userId, roles)

这样,我们只会调用PostPassword将密码发送到ApiController。在客户端,只有一个 Ajax 调用。它在我们将进行更新的服务器上。好处当然是减少了通过 Internet 传输的数据。

如果可能,将所有不同的POST 调用引导到ApiController 中的相应操作的正确方法是什么?

请帮助我们。谢谢大家。

【问题讨论】:

    标签: ajax rest asp.net-mvc-4 asp.net-web-api


    【解决方案1】:

    我认为,在大多数情况下,无需进行多次发布操作。典型案例是消费者需要编辑用户。因此,她/他需要先加载用户数据以显示在编辑表单上。编辑完成后,消费者可以点击保存按钮提交数据并在api控制器上调用POST动作。

    如果你的情况不同,你应该有值类型的可空属性,然后在控制器中检查的逻辑是如果任何属性为空,它不应该将该属性更新到数据库中。

    【讨论】:

    • 感谢您的回复。但可能不需要为编辑表单加载所有用户数据。比如说,如果一个人需要更新他/她的密码,只会显示一个文本框来接受输入。带有 uerId 和新密码的 json 足以完成这项工作。那么,我们怎样才能只 POST 整个用户数据的一部分并获得部分更新呢?
    • 对于您的情况,您只需将密码 POST 回服务器,用户的其他属性将为空。更新数据库的代码,检查每个属性是否不为空,所有不为空的属性都会被更新。
    【解决方案2】:

    每个控制器操作名称只能有一个发布操作。也就是说,你不能这样做

    // NOT VALID:
    public ActionResult UpdateUser(string newPassword) { }
    public ActionResult UpdateUser(List<string> newRoles) { }
    

    但是,动作的参数当然可以为空。如果给定的 HTTP 请求中没有提供给定的属性,则控制器中的属性值将为 null。

    // VALID:
    public ActionResult UpdateUser(string newPassword, List<string> newRoles) 
    { 
        if (newPassword != null) { } // It must have been supplied
        if (newRoles != null) { } // It must have been supplied
    }
    

    或者,您可以拥有相关的控制器操作,每个操作都处理您的一个用例,例如更新密码(...),更新地址(...),...

    【讨论】:

    • 什么是“相关控制器”?是普通的 MVC 控制器还是 ApiController?
    • 抱歉,我在回复中遗漏了一个词,让我感到困惑。已更新,包括示例。
    • 看起来您的示例在 MVC 中 Controller 而不是 ApiController,因为返回的类型是 ActionResult。但是您的 VALID 示例确实启发了我,我可以以相同的方式执行 POST 操作: public void Post(string newPassword, List newRoles) { if ... if ... } 我将进行测试运行并在此处报告结果。感谢您的帮助。
    • 刚刚在ApiController实现,我们只能POST单个复杂模型。没有办法Post(string newPassword, List&lt;string&gt; newRoles)。太可惜了!
    猜你喜欢
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    相关资源
    最近更新 更多