【问题标题】:Custom model binder for complex model with collection of polymorphic objects具有多态对象集合的复杂模型的自定义模型绑定器
【发布时间】:2014-12-29 20:15:18
【问题描述】:

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

我有下一个模型结构:

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
}

我想编写这样的活页夹来获取继承者的集合。

【问题讨论】:

  • new SomeEntity().CustomAttributes.Add(myModel); 不工作吗?
  • @AndreiV,我想你不明白我的意思。我想在我的操作中绑定 SomeEntity。
  • 不,我不知道。你能澄清一下吗?
  • 你能把你的View 展示给SomeEntity 模型吗?
  • @MaxBrodin,我在我的问题中写了更多细节。

标签: c# asp.net-mvc custom-model-binder


【解决方案1】:

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

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

请看看这个working Github sample

【讨论】:

  • 太棒了!伙计,你让我很开心!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多