【问题标题】:Pass json with multi-type lists to web api将具有多类型列表的 json 传递给 web api
【发布时间】:2015-02-04 19:30:17
【问题描述】:

我希望能够将具有多类型列表的对象传递给 web api 调用,但似乎如果我没有明确声明属性,web api 就会忽略数据。

您可以在下面看到,接口用作占位符以允许 C# 中的多类型列表,但似乎我们将 json 字符串传递给 web api,由于 DTO 不匹配,它没有映射值。

即将到来的 DTO:

public class ValueCheckTestDto
{
    public List<IValueCheckGroup> Groups { get; set; }
}

使用的类和接口

public class ValueCheck : IValueCheckGroup
{
    public ValueCheckOperators Operator { get; set; }
    public List<IValueCheckGroup> ValueCheckGroups{ get; set; }
}

public class ValueCheckExpression : IValueCheckGroup
{
    public int AsocDataFieldID { get; set; }
    public string Operand { get; set; }
}

public interface IValueCheckGroup
{
}

示例 JSON

{
    Groups: [{
        AsocDataFieldID: 3,
        Operand: "2323"
    }]
}

更复杂一点的 JSON 字符串版本

{
    Groups: [{
        Operator: "OR",
        ValueCheckGroups: [{
            Operator: "OR",
            ValueCheckGroups: [{
                AsocDataFieldID: 3,
                Operand: "test string"
            }]
        },{
            Operator: "AND",
            ValueCheckGroups: [{
                AsocDataFieldID: 4,
                Operand: "test string 2"
            }]
        }]
    }]
}

【问题讨论】:

    标签: c# json asp.net-web-api2 dto


    【解决方案1】:

    您需要创建一个自定义的 JsonConverter,如 here 所述

    您的自定义转换器将如下所示。

    public class IValueCheckGroupCreationConverter : JsonCreationConverter<IValueCheckGroup>
        {
            protected override IValueCheckGroup Create(Type objectType, JObject jsonObject)
            {
                bool isExpression = jsonObject["AsocDataFieldID"] == null ? false : true;
                if(isExpression) {
                        return new ValueCheckExpression ();
                } else {
                    return new ValueCheck();
                }   
            }
        }
    

    然后您可以在手动调用 JsonConvert.DeserializeObject 或将此属性添加到“组”字段时使用转换器:[JsonConverter(typeof(IValueCheckGroupCreationConverter))]

    【讨论】:

      【解决方案2】:

      您正在尝试将 dynamic Json 传递给 WebApi,但反序列化需要类型化结构。

      处理此问题的一种方法是期望 JObject 作为 WebApi 操作方法的参数:

      public async Task<IHttpActionResult> Get(JObject q)
      {
          dynamic query = q; // cast to dynamic
      
          foreach(var @group in query.Groups)
          {
              var op = @group.Operator; // or group["Operator"]
              // do something
          }
      
          throw new NotImplementedException();
      }
      

      你也可以写一个自定义的Model Binder

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-30
        • 1970-01-01
        • 1970-01-01
        • 2021-12-31
        • 2016-09-25
        • 2016-06-12
        • 1970-01-01
        • 2018-04-12
        相关资源
        最近更新 更多