【发布时间】:2019-07-06 18:59:43
【问题描述】:
我正在尝试为模型的 DateTime 类型属性应用自定义模型绑定器。 这是 IModelBinder 和 IModelBinderProvider 的实现。
public class DateTimeModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(DateTime))
{
return new BinderTypeModelBinder(typeof(DateTime));
}
return null;
}
}
public class DateTimeModelBinder : IModelBinder
{
private string[] _formats = new string[] { "yyyyMMdd", "yyyy-MM-dd", "yyyy/MM/dd"
, "yyyyMMddHHmm", "yyyy-MM-dd HH:mm", "yyyy/MM/dd HH:mm"
, "yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss"};
private readonly IModelBinder baseBinder;
public DateTimeModelBinder()
{
baseBinder = new SimpleTypeModelBinder(typeof(DateTime), null);
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult != ValueProviderResult.None)
{
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
var value = valueProviderResult.FirstValue;
if (DateTime.TryParseExact(value, _formats, new CultureInfo("en-US"), DateTimeStyles.None, out DateTime dateTime))
{
bindingContext.Result = ModelBindingResult.Success(dateTime);
}
else
{
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, $"{bindingContext} property {value} format error.");
}
return Task.CompletedTask;
}
return baseBinder.BindModelAsync(bindingContext);
}
}
这里是模型类
public class Time
{
[ModelBinder(BinderType = typeof(DateTimeModelBinder))]
public DateTime? validFrom { get; set; }
[ModelBinder(BinderType = typeof(DateTimeModelBinder))]
public DateTime? validTo { get; set; }
}
这里是控制器动作方法。
[HttpPost("/test")]
public IActionResult test([FromBody]Time time)
{
return Ok(time);
}
测试时,不会调用自定义活页夹,但会调用默认的 dotnet 活页夹。据官方documentation称,
ModelBinder 属性可以应用于单个模型属性 (例如在视图模型上)或以操作方法参数指定一个 仅用于该类型或操作的特定模型绑定器或模型名称。
但它似乎不适用于我的代码。
【问题讨论】:
标签: c# asp.net-core model-binding