I have an object that will be used with multiple clients. The object has a set of fixed properties that are common among all clients. Here is an example of what an object may look like:
public class Applicant
{
public string ApplicantId { get; set; }
public string ProducerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
...
public List<dynamic> Information { get; set; }
}
We will be receiving this through a Web API POST. So I have this controller signature:
[HttpPost]
public void Post([FromBody] dynamic value)
{
var converter = new ExpandoObjectConverter();
dynamic input = JsonConvert.DeserializeObject<Loan>(value,converter);
}
But when I run this code, NewtonSoft keeps giving me the error
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'The best overloaded method match for 'Newtonsoft.Json.JsonConvert.DeserializeObject<ExpandoObjectTestAPI.Models.Loan>(string, params Newtonsoft.Json.JsonConverter[])' has some invalid arguments'
Looking around it appears that it is having problem with the dynamic type that is passed in. So how would I pass in this JSON so I can parse it using the ExpandoObjectConverter?
This doesn't answer the question using dynamic, but it's worth considering avoiding this by using a Dictionary instead to model custom properties. The following works for generic key/value pairs:
public class Applicant
{
...Standard properties
public IDictionary<string, object> Custom { get; set; }
}
It would accept JSON with arbitrary dynamic fields nested under your "Custom" namespace:
{
"applicationId": "123",
"producerId": "456",
"custom": {
"favoriteAnimal": "turtles",
"someRandomMetadata": 42,
"someUnforeseenList": ["foo", "bar"]
}
}
I've had good luck handling user-defined extension fields this way. It also has the arguable advantage of isolating custom fields into a nested namespace to isolate from built-in data.