ASP.NET Core中的多态模型绑定

I'm trying to use the example given here to get polymorphic model binding to work with ASP.NET Core 3.1. The problem is I get null for my value.

我的模型资料提供者:

public class BaseDtoModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context.Metadata.ModelType != typeof(BaseDto))
        {
            return null;
        }

        var derived = new[] {typeof(FirstDto), typeof(SecondDto)};
        var binders = new Dictionary<Type, (ModelMetadata, IModelBinder)>();

        foreach (var type in derived)
        {
            var metadata = context.MetadataProvider.GetMetadataForType(type);
            binders[type] = (metadata, context.CreateBinder(metadata));
        }

        return new BaseDtoModelBinder(binders);
    }
}

而我的模型活页夹:

public class BaseDtoModelBinder : IModelBinder
{
    private readonly Dictionary<Type, (ModelMetadata, IModelBinder)> _binders;

    public OtpRequestDtoModelBinder(Dictionary<Type, (ModelMetadata, IModelBinder)> binders)
    {
        _binders = binders ?? throw new ArgumentNullException(nameof(binders));
    }

    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var type = ModelNames.CreatePropertyModelName(bindingContext.ModelName, "type");
        var value = bindingContext.ValueProvider.GetValue(type).FirstValue;

        IModelBinder binder;
        ModelMetadata metadata;
        if (value.Equals("first", StringComparison.InvariantCultureIgnoreCase))
        {
            (metadata, binder) = _binders[typeof(FirstDto)];
        }
        else if (value.Equals("second"))
        {
            (metadata, binder) = _binders[typeof(SecondDto)];
        }
        else
        {
            bindingContext.Result = ModelBindingResult.Failed();
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, $"{value} type is not supported.");
            return;
        }

        var newBindingContext = DefaultModelBindingContext.CreateBindingContext(
            bindingContext.ActionContext,
            bindingContext.ValueProvider,
            metadata,
            null,
            bindingContext.ModelName);

        await binder.BindModelAsync(newBindingContext);
        bindingContext.Result = newBindingContext.Result;

        if (newBindingContext.Result.IsModelSet)
        {
            bindingContext.ValidationState[newBindingContext.Result] = new ValidationStateEntry
            {
                Metadata = metadata
            };

            bindingContext.ModelState = newBindingContext.ModelState;
        }
    }
}

My model binder gets called correctly. However, I see that bindingContext.ModelName is always empty and the problem is

var value = bindingContext.ValueProvider.GetValue(type).FirstValue;

always returns null.

我的控制器看起来像:

[HttpPost("hello")]
public async Task<IActionResult> SendOtp([FromBody] BaseDto request)
{
     // Controller logic.
}

我的DTO课程是:

public abstract class BaseDto
{
    public string Id { get; set; }
    public Type type { get; set; } // Here type is an enum.

    public FirstDto first { get; set; } // Or
    public SecondDto second { get; set; } // Depending on the type
}

public class FirstDto : BaseDto {}
public class SecondDto : BaseDto {}
评论