4

I need to run some code to further databind some model after the default model binding is done. I don't want to completely replace the existing model binding.

This question explains how this is done in pre-CORE ASP.NET: ASP.NET MVC - Mixing Custom and Default Model Binding

However that approach doesn't seem to work in ASP.NET Core because there is no DefaultModelBinder class any more.

What alternative can be used in ASP.NET Core?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Paymon
  • 1,173
  • 1
  • 9
  • 26

1 Answers1

1

You can leverage the ComplexTypeModelBinder to do the actual work, then inject your own logic after it is done.

For example (assuming your custom type is MyCustomType):

public class MyCustomType
{
    public string Foo { get; set; }
}

public class MyCustomTypeModelBinder : IModelBinder
{
    private readonly IDictionary<ModelMetadata, IModelBinder> _propertyBinders;

    public MyCustomTypeModelBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders)
    {
        this._propertyBinders = propertyBinders;
    }

    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var complexTypeModelBinder = new ComplexTypeModelBinder(this._propertyBinders);

        // call complexTypeModelBinder
        await complexTypeModelBinder.BindModelAsync(bindingContext);

        var modelBound = bindingContext.Model as MyCustomType;

        // do your own magic here
        modelBound.Foo = "custominjected";
    }
}

public class MyCustomTypeModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context.Metadata.ModelType == typeof(MyCustomType))
        {
            var propertyBinders = new Dictionary<ModelMetadata, IModelBinder>();

            for (var i = 0; i < context.Metadata.Properties.Count; i++)
            {
                var property = context.Metadata.Properties[i];
                propertyBinders.Add(property, context.CreateBinder(property));
            }

            return new MyCustomTypeModelBinder(propertyBinders);
        }

        return null;
    }
}

Then register it:

services.AddMvc(options =>
{
    options.ModelBinderProviders.Insert(0, new MyCustomTypeModelBinderProvider());
});
haim770
  • 48,394
  • 7
  • 105
  • 133