title: Apply Custom Model Binder to Object Property in asp.net core
body: <p>I am trying to apply custom model binder for DateTime type property of model. 
  Here is the IModelBinder and IModelBinderProvider implementations.</p>
  
  <pre><code>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);
      }
  }
  </code></pre>
  
  <p>And here is the model class</p>
  
  <pre><code>public class Time
   {
          [ModelBinder(BinderType = typeof(DateTimeModelBinder))]
          public DateTime? validFrom { get; set; }
  
          [ModelBinder(BinderType = typeof(DateTimeModelBinder))]
          public DateTime? validTo { get; set; }
   }
  </code></pre>
  
  <p>And here is the controller action method.</p>
  
  <pre><code>[HttpPost("/test")]
  public IActionResult test([FromBody]Time time)
  {
  
       return Ok(time);
  }
  </code></pre>
  
  <p>When tested, the custom binder is not invoked but the default dotnet binder is invoked. According to the official <a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-2.2#recommendations-and-best-practices" rel="noreferrer">documentation</a>, </p>
  
  <blockquote>
    <p>ModelBinder attribute could be applied to individual model properties
    (such as on a viewmodel) or to action method parameters to specify a
    certain model binder or model name for just that type or action.</p>
  </blockquote>
  
  <p>But it seems not working with my code. </p>