Reputation: 1227
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
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; }
}
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
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
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