【问题标题】:DTO constructor argument validation and WebApi responseDTO 构造函数参数验证和 WebApi 响应
【发布时间】:2017-04-17 20:59:21
【问题描述】:

如果我开发一个 WebApi 动作方法

[Route]
public string Put([FromBody]MyClass value)

在构造函数中使用具有参数验证的 MyClass 类真的是个坏主意,例如:

public MyClass(string value)
{
    if (!_pattern.IsMatch(value))
            throw new ArgumentException($"Value should match RegEx: {_pattern}", nameof(value));
}

因此,在错误的请求中,它会从 JsonMediaTypeFormatter.ReadFromStreamAsync 引发异常,该异常发生在控制器或操作过滤器之外,因此我还没有找到通过ArgumentException 消息中的真实问题描述来响应客户端的方法。

即使这样的参数检查也没有放在 DTO 中,这对 WebApi 和真实(域模型)中唯一允许的 MyClass 是否应该创建相应的简单合同类而根本没有任何检查?

【问题讨论】:

    标签: c# .net oop asp.net-web-api2 dto


    【解决方案1】:

    使用来自 API 的结构化消息创建一个 ErrorDto。有一个ExceptionFilter 来处理这个是常见的做法。

    关于验证反馈,您可能想看看this article by Martin Fowler about avoiding to use exceptions as an approach to validation

    话虽如此,您可能会找到this library interesting

    【讨论】:

    • 不幸的是 ExceptionFilterAttribute 只处理控制器动作抛出的异常。
    • 但是验证中的“异常通知”看起来很有意义。
    • 我会避免在 ActionFilters 上使用业务逻辑。但是您仍然可以通过在 web.config 中添加自定义 <httpErrors> 部分来捕获这些异常
    • 实际上我有自己的主机 OWIN(没有 web.config),但没关系 - 我已经决定将验证与 DTO 分开。
    【解决方案2】:

    顺便说一句,我发现如果 Dto 从构造函数(控制器外)抛出 ArgumentException,你仍然可以使用

    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }
    

    [Route]
    [ValidateModel]
    public string Put([FromBody]MyClass value)
    

    这将响应客户

    {
      "Message": "The request is invalid.",
      "ModelState": {
        "value": [
          "Value should match RegEx: ...\r\nParameter name: value"
        ]
      }
    }
    

    但当纯 DTO 与 DataAnnotations 指定全部时,它仍然允许仅通知第一个发现的问题。

    【讨论】:

      猜你喜欢
      • 2022-06-18
      • 1970-01-01
      • 2013-02-17
      • 2010-12-27
      • 1970-01-01
      • 2012-09-18
      • 2019-04-02
      • 2018-08-26
      • 1970-01-01
      相关资源
      最近更新 更多