将带有多种类型列表的json传递给web api

时间:2015-02-04 19:30:18

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

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

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

Icoming 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"
            }]
        }]
    }]
}

2 个答案:

答案 0 :(得分:1)

您需要按照here

创建自定义JsonConverter

您的自定义转换器会看起来像这样。

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))]

答案 1 :(得分:0)

您尝试将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