【问题标题】:Bind specified property of the WebAPI controller's model绑定 Web API 控制器模型的特定属性
【发布时间】:2015-02-27 19:55:24
【问题描述】:

我只想绑定 WebAPI 控制器模型的指定属性,并跳过所有其他属性到 DefaultModelBinder

例如我有json,应该传递给WebAPI控制器:

{
   prop1: 1,
   prop2: "b",
   prop3: "c",
   currentTime: "Fri Feb 27 2015",
   references: 
   [
      { name: "Name 1", type: "Info"  },
      { name: "Name 2", type: "Warn" }
   ]
}

在服务器端有一个带有以下签名的HttpPost 操作:

[HttpPost]
public void SaveObject(ReferenceModel model)
{
   ...
} 

ReferenceModel 在哪里:

public class ReferenceModel
{
   public int Prop1 {get; set;}
   public string Prop2 {get; set;}
   public string Prop3 {get; set;}
   public DateTime CurrentTime {get; set;}
   public List<BaseReferenceItem> References {get; set;}
}

我需要自定义绑定References 属性,因为我想在运行时通过派生类型的对象初始化这个属性。

例如,如果我将获得值为1Prop1,那么我需要通过DerivedReferenceType1 类型的对象来初始化这个集合:

Model.References = new List<BaseReferenceItem>()
   {
     new DerivedReferenceType1(){...},
     new DerivedReferenceType1(){...}
   }

如果我将得到 Prop1 的值 2 - 类型为 DerivedReferenceType2 等等。

我在ModelBinder 中找到了潜在的解决方案,但我不想绑定模型上的所有属性。

我知道它可以很容易地在 MVC 模型绑定器中通过调用来实现

base.BindModel(controllerContext, bindingContext);

但是如何在 WebAPI 中做到这一点?

谢谢!

【问题讨论】:

    标签: asp.net .net c#-4.0 asp.net-web-api


    【解决方案1】:

    一种可能性是编写一个自定义JsonConverter 来处理这种情况:

    public class MyConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(ReferenceModel);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jsonObject = JObject.Load(reader);
            var result = new ReferenceModel();
            serializer.Populate(jsonObject.CreateReader(), result);
    
            result.References = new List<BaseReferenceItem>();
            foreach (var obj in jsonObject.GetValue("references", StringComparison.InvariantCultureIgnoreCase))
            {
                if (result.Prop1 == 1)
                {
                    result.References.Add(obj.ToObject<DerivedReferenceType1>(serializer));
                }
                else if (result.Prop1 == 2)
                {
                    result.References.Add(obj.ToObject<DerivedReferenceType2>(serializer));
                }
                else
                {
                    throw new NotSupportedException(result.Prop1 + " is not supported value for Prop1");
                }
            }
    
            return result;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    

    然后你可以用这个自定义转换器装饰你的主视图模型:

    [JsonConverter(typeof(MyConverter))]
    public class ReferenceModel
    {
        public int Prop1 { get; set; }
        public string Prop2 { get; set; }
        public string Prop3 { get; set; }
        public DateTime CurrentTime { get; set; }
        public List<BaseReferenceItem> References { get; set; }
    }
    

    或者,如果您希望在不修改视图模型的情况下执行此操作,您可以随时在引导过程中注册您的自定义转换器:

    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        ...
    
        var jsonFormatter = config.Formatters.JsonFormatter;
    
        jsonFormatter.SerializerSettings.Converters.Add(new MyConverter());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-21
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 2020-01-28
      • 2016-12-21
      • 2012-08-28
      • 2018-12-07
      相关资源
      最近更新 更多