Why doesn't the web API controller action override the deserialization of the child properties of the child properties?

I am sending a json payload in a PUT request for a web API controller action. The action in question has a signature that looks like this:

public IHttpActionResult Post([FromBody]SaveThingRequest request)

      

SaveThingRequest looks something like this:

public class SaveThingRequest
{
    public List<ElementInfo> Elements { get; set; }

    public class ElementInfo
    {
        public List<ElementSettingInfo> Settings { get; set; }

        public class ElementSettingInfo
        {
            public string Name { get; set; }
            public string Value { get; set; }
        }
    }
}

      

I am sending json to the body of the request containing the Customized Items. I confirmed this by doing manual deserialization in a controller action and confirming that the JSON has a structure that looks something like this:

{
    Elements: [
        {
            Settings: [
                {
                    Name: 'Name 1',
                    Value: 'Value 1'
                },
                {
                    Name: 'Name 2',
                    Value: 'Value 2'
                }
            ]
        },
        {
            Settings: [
                {
                    Name: 'Name 1',
                    Value: 'Value 1'
                },
                {
                    Name: 'Name 2',
                    Value: 'Value 2'
                }
            ]
        }
    ]
}

      

However, when .NET deserializes the payload and creates the SaveThingRequest, my items get populated, but they all have a null Settings property. I don't know how else to fix this. Anyone have any thoughts on what might be going on here?

+3


source to share


4 answers


This question should be removed. It works as advertised. My problem was that I had an additional property in JSON named "settings" (lower case) that the deserializer was trying to match, as NewtonSoft's deserialization tries to match case insensitive if no case sensitive code is found. I was able to find out what was going on by changing the method reference:

public IHttpActionResult Post([FromBody]object request)

      

and then adding this to the method implementation:

var result = JsonConvert.DeserializeObject<SaveThingRequest>(request.ToString());

      



I have a deserialization exception saying:

Cannot deserialize the current JSON object (eg {"name": "value"}) to type 'System.Collections.Generic.List`1 [Noteable.Contracts.ClinicalReports.SaveThingRequest + ElementInfo + ElementSettingInfo] because it requires a JSON array (eg [1,2,3]) to deserialize correctly. To fix this error, either change JSON to a JSON array (for example, [1,2,3]) or change the deserialized type to be normal .NET type (for example, not a primitive integer type, not a set type like an array or a list) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to be deserialized from a JSON object. Track 'Items [0] .settings.TextSize', line 11, position 20.

The end of the post showed me what was deserialized when the deserializer failed and pointed me in the right direction. = [

+13


source


I am stuck with the same issue. However, the problem was something else.

In my case, the property that is not getting serialized was declared without a share specifier. I announced it publicly and everything went great.



Hope this helps someone stuck in this situation. It took me 20 minutes to reach this solution.

+3


source


Make sure you don't do something stupid like me and send a partially "string" JSON string from the browser instead of a JSON object.

See the problem? I didn't do this until I tried to deserialize it from a string, and then realized that shippingAddress

it was a string myself and not an actual JSON object. The rest of the object was proper JSON, but I accidentally serialized the shippingAddress field.

{"fspID": 571285, "foo": 444, "shippingAddress": "{\" countryCode \ ": \" US \ ", \" firstName \ ": \" Test User \ ", \" lastName \ ": null, \ "address1 \": \ "1 Main St4 \", \ "address2 \": null, \ "company \": null, \ "city \": \ "San Jose \", \ "stateOrProvince \" : \ "California \", \ "stateCd \": \ "CA \", \ "zipOrPostal \": \ "95131 \", \ "countryName \": \ "United States \", \ "countryDesc \": \ "United States \", \ "phone \": null, \ "phone2 \": null} "}

0


source


If you are using JSON.NET and an attribute [JsonProperty]

to name a property - make sure you don't accidentally copy pasting the same property twice and forget to update the string value.

 [JsonProperty("billingAddress")]
 public Address BillingAddress { get;set; }

 [JsonProperty("billingAddress")]
 public Address ShippingAddress { get;set; }

      

This will cause Newtonsoft.Json.JsonSerializationException

that you won't actually see it and mess up the model.

0


source







All Articles