1

我以非标准方式编写 Web API 控制器,将参数作为动态对象获取。

这会导致 NSwag 出现问题。因为方法定义中没有参数,NSwag 无法生成需要的东西。

我想知道在这种情况下是否有任何使用 NSwag 的选项。也许我可以将一些属性添加到方法中,以便 NSwag 能够生成 API?

[HttpPost]
[ActionName("create-account")]
public IHttpActionResult CreateAccount()
{
    var body = Request.Content.ReadAsStringAsync().Result;

    dynamic json = Utils.GetJsonBody(body);

    if (!Utils.GetJsonPropertyValueByPropertyName<String>(json, "email", out String email))
    {
        return Content(HttpStatusCode.BadRequest, "Please provide a valid email.".AsApiMessageResult());
    }

    if (!Utils.GetJsonPropertyValueByPropertyName<String>(json, "name", out String name))
    {
        return Content(HttpStatusCode.BadRequest, "Please provide an account name.".AsApiMessageResult());
    }

    if (!Utils.GetJsonPropertyValueByPropertyName<String>(json, "domain", out String domain))
    {
        return Content(HttpStatusCode.BadRequest, "Please provide a valid domain.".AsApiMessageResult());
    } 
4

1 回答 1

4

Swagger 的特点是它使用你的方法的签名来生成你的代码如何工作的文档。绕过所有正常的 Web API 并选择读取原始 HTTP 请求意味着 Swagger 无法看到您在做什么,从而使其难以自动确定您的代码在做什么。您在读取原始请求和使用动态时所做的技术还有许多其他缺点。

  • 您没有为您的对象获得 Intellisense
  • 它不是功能性的,这意味着通过查看输入和输出所采用的方法很难判断,这使得它更难理解
  • 对代码进行单元测试更加困难,因为现在您必须为 Web API 控制器构建 HTTP 请求
  • 与使用适当的对象做事相比,它需要更多的代码

相反,我们应该定义一个合适的模型来发布到我们的 API。这将允许 Web API 完成其工作,模型绑定器将处理将请求转换为 CreateAccountRequest 的实例。

public class CreateAccountRequest
{
    public string Email { get; set; }

    public string Name { get; set; }

    public string Domain { get; set; }
}

然后我们可以让我们的操作方法将这个类的实例作为参数。

[HttpPost]
[ActionName("create-account")]
public IHttpActionResult CreateAccount(CreateAccountRequest request)
{
    //now here you can validate the request if you want
}

Swagger 现在应该可以理解这个方法了,让 NSwag 生成一个有用的客户端。

请注意,您应该查看 Web API 为模型验证提供的内置工具,而不是进行自定义 C# 验证。然后您需要做的就是检查 ModelState,而不是手动检查每个参数。其他工具也可以查看模型的属性,从而增强工具体验。

于 2019-01-19T14:15:42.110 回答