Mad Eddie
Mad Eddie

Reputation: 1227

Convert JSON object to C# model Web API 2

This is my 4th production level system using AngularJS and web API 2 C# backend. I am not coming to this with no experience BUT....I just cannot get the very simple conversion working. I normally use complex models between the Angular UI and Web API 2 backend without issue so very frustrated as this is so simple.

I am posting the JSON below:

{
"appSelection": [
  {
  "name": "Withdrawal Service",
  "selected": true
  }
],
"dateSelection": {
  "startDate": "2016-06-13T23:00:00.000Z",
  "endDate": "2016-07-27T07:52:03.510Z"
},
"eventTypes": [
  {
  "name": "Fail",
  "selected": true
  },
  {
  "name": "Success",
  "selected": true
  }
]
}

To a Web API controller: (edited for brevity)

        [HttpPost]
        [Route("search")]
        [ResponseType(typeof(ProcessLog[]))]
        public async Task<IHttpActionResult> getLogs(LogRequest request)
        {
            string requestBody = string.Empty;
            using (var stream = new MemoryStream())
            {
                var context = (HttpContextBase)Request.Properties["MS_HttpContext"];
                context.Request.InputStream.Seek(0, SeekOrigin.Begin);
                context.Request.InputStream.CopyTo(stream);
                requestBody = Encoding.UTF8.GetString(stream.ToArray());
            }

Which accepts this model:

public class LogRequest
        {
            public DateViewModel DateSelection { get; set; }
            public NameAndSelect[] appSelection { get; set; }
            public NameAndSelect[] eventTypes { get; set; }
        }

        public class NameAndSelect
        {
            public bool selected { get; set; }
            public string name { get; set; }
        }
        public class DateViewModel
        {
            public DateTime startDate { get; set; }
            public DateTime endDate { get; set; }
        }

The output from the requestBody is

{"appSelection":[{"name":"Withdrawal Service","selected":true}],"dateSelection":{"startDate":"2016-06-13T23:00:00.000Z","endDate":"2016-07-27T07:52:03.510Z"},"eventTypes":[{"name":"Fail","selected":true},{"name":"Success","selected":true}]}

Which shows that the JSON is being correctly POST'ed to the web API controller but the auto model binding is failing. The request object (web api receiving model) is

DateSelection : null
appselection : null
eventTypes : null

I just cannot see why and where. Been trying this for > 2 days! would really appreciate a fresh pair of eyes.

Thanks in advance

Update #1:

Changed model to the below with still failing auto binding

public class LogRequest
        {
            public DateViewModel DateSelection { get; set; }
            public List<NameAndSelect> appSelection { get; set; }
            public List<NameAndSelect> eventTypes { get; set; }
        }

Update #2:

I have tried simplifying the model to

public class LogRequestViewModel
    {
        public string testString { get; set; }
        public DateTime startDate { get; set; }
        public DateTime endDate { get; set; }
        public DateSelection dateselection { get; set; }
     }
public class DateSelection
     {
        public string startDate { get; set; }
        public string endDate { get; set; }
     }

and posting:

{"teststring":"plap","startdate":"2016-07-27T09:28:38.404Z","enddate":"2016-07-27T09:28:38.404Z","dateselection"
:{"startdate":"2016-07-27T09:28:38.404Z","enddate":"2016-07-27T09:28:38.404Z"}}

I receive:

dateselection:null
enddate:      {27/07/2016 10:28:38}
startdate:    {27/07/2016 10:28:38}
teststring:   "plap"

Which suggests it is able to convert the datetime without issue but deeper objects are causing problems

Upvotes: 4

Views: 2963

Answers (2)

Mad Eddie
Mad Eddie

Reputation: 1227

Thanks to @Smoksnes I commented out all JSON formatters which are in the startup classes and classes in App_Start. Unfortunately this did not resolve the problem. When run-commenting all the commented out lines I found the below in my WebApiConfig.cs

var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
            jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            jsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
            jsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
            jsonFormatter.SerializerSettings.MaxDepth = 1;

The bottom line! Doh. Commenting ALL JSON formatters hadn't fixed it but re-enabling them all APART from this line fixed it. I guess I needed the combination of some of the other formatters but not MaxDepth one.

Thanks All

Upvotes: 3

Pankaj Gupta
Pankaj Gupta

Reputation: 388

    public class AppSelection
{
    public string name { get; set; }
    public bool selected { get; set; }
}

public class DateSelection
{
    public string startDate { get; set; }
    public string endDate { get; set; }
}

public class EventType
{
    public string name { get; set; }
    public bool selected { get; set; }
}

public class RootObject
{
    public List<AppSelection> appSelection { get; set; }
    public DateSelection dateSelection { get; set; }
    public List<EventType> eventTypes { get; set; }
}
change this model to your model and then try hope it will useful for you

Upvotes: 0

Related Questions