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 {}