Search code examples
jsonserializationasp.net-web-apijsonserializer

Deserializing JSON string to C#


I have a JSON array, which looks like this:

{[
  {
    "personnelId": 201,
    "occupationIds": [
      4,
      5
    ]
  },
  {
    "personnelId": 202,
    "occupationIds": [
      5
    ]
  }
]}

I'm receiving this string through a JObject in my ASP.NET Web API controller:

var jPersonnelAndOccupationIds = json["personnelAndOccupationIds"];

I've had success deserialiizing various data structures through JObject but this keeps giving a RuntimeBinderException, what data structure would be best suited for that JSON string, I've tried a lot of thing, this IMO is the most suitable List<PersonnelOccupationsVm> where PersonnelOccupationsVm looks like this:

public class PersonnelOccupationsVm
    {

        public long personnelId { get; set; }
        public List<long> occupationIds { get; set; }
    }

which I desrialize like this:

var personnelIdsAndOccupationsKvp = jPersonnelAndOccupationIds.ToObject(new List<PersonnelOccupationsVm>());

and I've tried

System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<List<PersonnelOccupationsVm>>(jPersonnelAndOccupationIds);

neither works. any ideas?

EDIT

As requested in the comments, I'm making my call like this (angular):

$http({
  method: 'POST',
  url: '/api/EnterprisePersonnelApi/SubmitOcupationalPersonnel/',
  data: JSON.stringify({ enterpriseId: enterpriseId, positionId: positionId,personnelAndOccupationIds: personnelAndOccupationIds }),
  }).success(function (data, status, headers, config) {
                      deferred.resolve(data);
  }).error(function (data, status, headers, config) {
                     deferred.reject(status);
});

and my web api action:

[System.Web.Http.HttpPost]
public CrudOperationResults SubmitOcupationalPersonnel(JObject jsonData){
dynamic json = jsonData;
var jPersonnelAndOccupationIds = json["personnelAndOccupationIds"];
var personnelIdsAndOccupations = jPersonnelAndOccupationIds.ToObject(new List<PersonnelOccupationsVm>());
.....
}

this given a RunTimeBinderexception, however when I call .ToString() while retrieving values from the JObject instance:

var jPersonnelAndOccupationIds = json["personnelAndOccupationIds"].ToString();

and (per shunty's suggestion)

var jPersonnelAndOccupationIds = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PersonnelOccupationsVm>>(jPersonnelAndOccupationIds);

this works fine, the leading and trailing curly braces were added while retieving my parameter values from JObject, calling .ToString() and deserializing it per above did the trick.


Solution

  • I'm not a particularly proficient Json user but, using the Newtonsoft stuff I'd try something like this (cut and pasted from LINQPad):

    void Main()
    {
        string json = "[{ \"personnelId\": 201, \"occupationIds\": [4,5]}, {\"personnelId\": 202,\"occupationIds\": [5]}]";
    
        var js = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PersonnelOccupationsVm>>(json);
        js.Dump();
    
    }
    
    public class PersonnelOccupationsVm
    {
        public int PersonnelId { get; set; }
        public List<int> OccupationIds { get; set; }
    
        public PersonnelOccupationsVm()
        {
            OccupationIds = new List<int>();
        }
    }
    

    Note that I had to trim the leading and trailing { } characters from the source Json.