【问题标题】:Web API 2 throw exception on invalid datetimesWeb API 2 在无效的日期时间抛出异常
【发布时间】:2018-07-02 09:17:18
【问题描述】:

我将日期从 JavaScript 客户端发送到 ASP.NET Web API 2 控制器作为 POST。

如果我发送一些不是日期的字符串,它将默默地转换为DateTime 最小值。我假设它默认为默认值(DateTime)。

我想在进入我的控制器动作之前抛出一个异常。 最好的方法是什么?

我尝试过的:

我尝试创建DateTimeConverterBase 的子类并将其添加到HttpConfiguration.Formatters.JsonFormatter.SerializerSettings.Converters。但只有WriteJson 函数会被调用。根据我的断点,永远不要ReadJson

【问题讨论】:

    标签: c# asp.net datetime asp.net-web-api2


    【解决方案1】:

    我之前使用Data Annotations 来实现Web API 中的模型验证。这是一个很好的解决方案,因为它是面向方面的,所以非常规避。

    这也是旧 MVC 进行模型验证的方式,并且工作方式相同。您只需将注释语法作为声明性属性应用到模型上:

    [Required]
    [DataType(DataType.DateTime)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")] // or something similar
    public DateTime? MyDate { get; set; }
    

    然后,您可以访问提供的 ModelState 静态实例,通过引用包含注释模型的程序集,该实例自动可用于您的控制器操作。然后,您可以将其传递给 CreateErrorResponse() 扩展的适当overload,Web API 将为您处理错误响应:

    if (!ModelState.IsValid)
    {
        // bad request
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
    } 
    

    我想在进入我的控制器动作之前抛出一个异常

    如果您真的想这样做,那么您可以通过实现OnActionExecuting()action filter 中实现相同的验证。我没有这样做,老实说,除了让你的控制器保持瘦身之外,我真的看不到其他好处。

    【讨论】:

    • 感谢您将我指向操作过滤器。我想我可能希望所有帖子都使用这个(你有什么理由不这样做吗?),所以它应该避免我打字。
    • @simmenilsson 老实说,我看不到在过滤器中这样做的好处。验证是一个业务问题,因此我认为属于控制器。此外,您还可以通过扩展控制器测试来更轻松地进行测试
    【解决方案2】:

    您可以创建一个操作并将其添加到您的管道中,检查 ModelState.IsValid 并将 400 状态返回给客户端。

    【讨论】:

    • 如果我检查我的方法,ModelState.IsValid 返回 true。 :/ 一个动作会产生影响吗?
    • 不,这不会有什么不同。无论哪种方式,模型绑定都是一样的。
    • 我认为它认为它在设置为 Min 后得到了一个很好的 DateTime。
    • 尝试标记属性[必填] 我想知道您发送的字段名称是否不匹配。
    • 谢谢!字段名称正确。但需要处理日期未定义或为空的情况。 ModelState.IsValid 负责其余的工作。
    【解决方案3】:

    从 js 代码中以字符串形式发送日期。在 web api 控制器中,根据您的日期格式尝试 datetime.parsedatetime.tryparse

    例如

       public IHttpActionResult Get([FromUri]string date)
       {
         DateTime dt = new DateTime();
         if (!DateTime.TryParse(date, null, System.Globalization.DateTimeStyles.RoundtripKind, out dt))
         {
              return BadRequest("incorrect input");
    
         }
       }
    

    【讨论】:

    • 谢谢,这是一种解决方法,但我想一劳永逸地处理它。不为项目中的每个 DateTime 属性添加代码。
    • 您可以尝试使用服务来解析日期时间。在需要的地方注入控制器。这样可以避免代码重写。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2015-04-15
    • 1970-01-01
    • 2014-05-15
    相关资源
    最近更新 更多