ASP.NET Core Controller中自定义DateTime ModelBinder被绕过问题
问题根因
你自定义的IsoDateModelBinder在ISO格式解析失败后,调用了默认的SimpleTypeModelBinder作为降级逻辑,这个内置绑定器会使用宽松规则解析多种日期格式,导致不符合要求的输入也能绑定成功,返回200状态码。
修复方案
直接移除降级逻辑,解析失败时主动标记绑定失败即可,修改后的模型绑定器代码如下:
using System; using System.Globalization; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ModelBinding; namespace WebApiDates { public class IsoDateModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "日期参数不能为空"); bindingContext.Result = ModelBindingResult.Failed(); return Task.CompletedTask; } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); var valueAsString = valueProviderResult.FirstValue; if (DateTime.TryParseExact(valueAsString, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeResult)) { bindingContext.Result = ModelBindingResult.Success(dateTimeResult); return Task.CompletedTask; } bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, $"日期格式不正确,仅支持ISO 8601格式(yyyy-MM-dd),收到的值为:{valueAsString}"); bindingContext.Result = ModelBindingResult.Failed(); return Task.CompletedTask; } } }
因为你的Controller标注了[ApiController]特性,ASP.NET Core会自动对绑定失败的请求返回400 BadRequest,无需额外编写校验逻辑。修改后重新运行测试,只有符合yyyy-MM-dd格式的输入会返回200,其余非法格式都会返回400,完全符合预期。
内容的提问来源于stack exchange,提问作者marcusturewicz
相关产品推荐
相关产品推荐

