scorpion5211
scorpion5211

Reputation: 1070

JSON Serialization Mystery

I have a MyParameters object that has a "auto reset" feature that will initialize some of its child object values to the default value. In this case it seems like all the values are getting over written from the Json object that user sends in except the Filters list. See below..

MyController.cs:

namespace xx.Controllers
{
    [Authorize("xx")]
    [Route("api/[controller]")]
    public class MyController : Controller
    {
        public async Task<ActionResult> Post([FromBody]MyParameters parameters)
        {    
            //at this point parameters.Filters include the following:
            //[1,2,3,4,5,6,7,1,3,4,5]
            ...
        }
    }

    public class MyParameters
    {
        public Options Options { get; set; } = new Options ();

        ....            
    }

    public class Options 
    {
        public Options () => Reset();
        public List<int> Filters { get; set; }
        ...

        public void Reset()
        {
            this.Filters = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
            ...
        }
    }
}

the request that is coming in from the UI looks like the following:

{  
   "Options":{  
      "Filters":[  
         1,
         3,
         4,
         5
      ],
      ...
}

How can I force the Filters to be over written instead of appended to the default values on the object.

EDIT:

I combined the comments and the answer agnelsix put and got it working by adding

services.AddMvc()
        .AddJsonOptions(options => options.SerializerSettings.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace);

in the Startup.cs.

Upvotes: 0

Views: 221

Answers (2)

angelsix
angelsix

Reputation: 392

That is how JSON works with lists.

You can change this behaviour with ObjectCreationHandling options:

var settings = new JsonSerializerSettings
{
    ObjectCreationHandling = ObjectCreationHandling.Replace
};

var jsonString = "{\"Options\":{\"Filters\":[1,2,3,4,5]}}";
var deserialize = JsonConvert.DeserializeObject<MyParameters>(jsonString, settings);

Upvotes: 2

Anup Sharma
Anup Sharma

Reputation: 2083

In deserialization, the constructor is not called, only all the properties are initialized. So whatever you initialize in the constructor is going to be overwritten. If you still want to keep the constructor values intact then call the Reset() method after serialization is completed like using OnDeserializedAttribute

Upvotes: 0

Related Questions