具有多态对象集合的复杂模型的自定义模型绑定器

本文关键字:模型 自定义 绑定 复杂 对象 集合 多态 | 更新日期: 2023-09-27 18:28:55

如何为具有多态对象集合的复杂模型编写自定义模型绑定器?

我有下一个模型结构:

public class CustomAttributeValueViewModel
{
    public int? CustomAttributeValueId { get; set; }
    public int CustomAttributeId { get; set; }
    public int EntityId { get; set; }
    public CustomisableTypes EntityType { get; set; }
    public string AttributeClassType { get; set; }
}
public class CustomStringViewModel : CustomAttributeValueViewModel
{
    public string Value { get; set; }
}
public class CustomIntegerViewModel : CustomAttributeValueViewModel
{
    public int Value { get; set; }
}

如果我想将CustomAttributeValueViewModel绑定到它的一些继承者,我会使用这样的自定义模型绑定器:

public class CustomAttributeValueModelBinder : DefaultModelBinder
{
    protected override object CreateModel(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext,
        Type modelType)
    {
        if (modelType == typeof(CustomAttributeValueViewModel))
        {
            var attributeClassType = (string)bindingContext.ValueProvider
                .GetValue("AttributeClassType")
                .ConvertTo(typeof(string));
            Assembly assembly = typeof(CustomAttributeValueViewModel).Assembly;
            Type instantiationType = assembly.GetType(attributeClassType, true);
            var obj = Activator.CreateInstance(instantiationType);
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, instantiationType);
            bindingContext.ModelMetadata.Model = obj;
            return obj;
        }
        return base.CreateModel(controllerContext, bindingContext, modelType);
    }
}

它非常有效。但现在我想将这样的模型绑定为另一个模型的集合项。例如:

public class SomeEntity
{
    // different properties here
    public IList<CustomAttributeValueViewModel> CustomAttributes { get; set; }
}

我该怎么做?

编辑:

我想绑定我从客户那里收到的发布数据。为了更清楚起见,这是我的POST HTTP请求的一个例子:

POST someUrl HTTP/1.1
User-Agent: Fiddler
Host: localhost
Content-Type: application/json; charset=utf-8
Content-Length: 115
{
  "ProductName": "Product Name",
  "CustomAttributeValues": [
    {
      "CustomAttributeId": "1",
      "Value": "123",
      "AttributeClassType": "namespace.CustomStringViewModel"
    }
  ]
}

我在行动中收到这些数据:

public void Save([ModelBinder(typeof(SomeBinder))] SomeEntity model)
{
    // some logic
}

我想写这样的活页夹,以获得继承人的收藏。

具有多态对象集合的复杂模型的自定义模型绑定器

您需要包含AttributeClassType、的完整路径

var valueProviderResult = bindingContext.ValueProvider
                            .GetValue(bindingContext.ModelName + ".AttributeClassType");

请看一下这个正在工作的Github示例