1

I want to be able to pass object with multi-type list to web api call, but it seems that if I don't explicitly state properties, web api just ignores the data.

Below you can see, that an Interface is used as placeholder to allow multi-type lists in C#, but it seems that wehn passing json string to web api, it does not map the values due to DTO mismatch.

Icoming DTO:

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

Used classes and interfaces

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
{
}

Example JSON

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

A bit more complex version of JSON string

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

2 Answers 2

1

You need to create a custom JsonConverter as mentioned here

Your custom converter would then look something like this.

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();
            }   
        }
    }

You can then use the converter when manually calling JsonConvert.DeserializeObject or add this attribute to your 'Groups' field : [JsonConverter(typeof(IValueCheckGroupCreationConverter))]

Sign up to request clarification or add additional context in comments.

Comments

0

You're trying to pass dynamic Json to WebApi but deserialization expect typed structures.

One way to handle this is to expect a JObject as an argument to your WebApi action method :

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();
}

You could probably write a custom Model Binder too.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.