Search code examples
c#json.netrestjson.net

Sending Json with nested array of JTokens to remote server - C#


I'm trying to send a json object to a remote 3rd party Web api url. I am building this object using c#

private string SendWebRequest(string url, string requestMethod, string bearer = null, object temp_obj_body = null)
{
    string result = null;
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
    httpWebRequest.ContentType = "application/json";
    httpWebRequest.Method = requestMethod.ToUpper();

    // Sets the Security Token
    if (bearer != null)
    {
        httpWebRequest.Headers.Add("Authorization", "Bearer " + bearer);
    }

    //Writes to the request service if body is present
    if (temp_obj_body != null)
    {
        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream(), Encoding.UTF8))
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.CheckAdditionalContent = true;
            settings.Formatting = Formatting.Indented;
            settings.MetadataPropertyHandling = MetadataPropertyHandling.Default;
            settings.NullValueHandling = NullValueHandling.Include;
            settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
            settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
            settings.StringEscapeHandling = StringEscapeHandling.Default;
            settings.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full;
            settings.TypeNameHandling = TypeNameHandling.All;
            settings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead;

            var json = JsonConvert.SerializeObject(temp_obj_body, settings);
            streamWriter.Write(json);
        }
    }

    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

    //Reads the response and gets the response.
    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
    {
        result = streamReader.ReadToEnd();
    }
    return result;

the serialized JSON object that is generated looks like this

{
    "ID": 1,
    "TypeID": 1,
    "UserName": "tempUser",
    "Attributes": "[{\"ID\":13023,\"Value\":\"Nonemp Status\"},
{\"ID\":13022,\"Value\":\"Research Status\"},
{\"ID\":13021,\"Value\":\"ACT\"},
{\"ID\":13024,\"Value\":\"Temp Status\"},
{\"ID\":13025,\"Value\":\"Temp\"}]"
}

The issue with this is with the "attributes" item. This is supposed to be a nested JArray. Unfortunately, this send method converts the JArray into a string and caused the upload to fail. When I re-write the object to be a JArray, everything passes.

Working
{
    "ID": 1,
    "TypeID": 1,
    "UserName": "tempUser",
    "Attributes": [{"ID":13023,"Value":"Nonemp Status"},
{"ID":13022,"Value":"Research Status"},
{"ID":13021,"Value":"ACT"},
{"ID":13024,"Value":"Temp Status"},
{"ID":13025,"Value":"Temp"}]
}

The nested "Attributes" JArray can be anywhere from 2 items or 20 items. Does anyone know how to serialize or create the JSON object like the "working" JSON version from a passed in c#.NET object?


Solution

  • Your Attributes property array value was serialized twice, so you have to parse it twice too.
    You can try this code:

    using Newtonsoft.Json;
    
    result = streamReader.ReadToEnd();
    
    var jObj = JObject.Parse(result);
    jObj["Attributes"] = JArray.Parse((string)jObj["Attributes"]);
    return jObj.ToString();