0

I am attempting to code a nested JSON object for an upload API endpoint. I am having issues forming the code for the nested object. When I call the endpoint to post the data to their site, I get a 400 Bad Request error. I am using Newtonsoft.Json. When I remove the DisciplineData from the string, it POSTs successfully, but data in the DisciplineData class is required.

public class UploadClassParameters
{
    public int CompYear { get; set; }
    public int CompID { get; set; }
    public string ClassNumber { get; set; }
    public List<Result> Results { get; set; }
}

public class Result
{ 
    public string Placing { get; set; }
    public int HorseID { get; set; }
    public Dressage DisciplineData  { get; set; }
}

public class Dressage  // THIS IS THE NESTED OBJECT
{
    public double TotalScore { get; set; }
    public double TotalPercent { get; set; }
    public string DressageLevel { get; set; }
}

Using the code shown here, the classes above create this (which fails when I call the endpoint):

{
  "CompYear": 2025,
  "CompID": 1214,
  "ClassNumber": "53",
  "Results": [
    {
      "Placing": "1",
      "HorseID": 5536384,
      "DisciplineData": {
          "TotalScore": 169.0,
          "TotalPercent": 67.6,
          "DressageLevel": "FIRST LEVEL, TEST 2",
      }
    }
  ]
}

To see how their data is formed, I called their GetClass endpoint, and this was returned:

{
  "CompYear": 2025,
  "CompID": 1214,
  "ClassNumber": "53",
  "Results": [
    {
      "Placing": "1",
      "ID": 5536384,
      "DisciplineData":{\"TotalScore\":169.0,\"TotalPercentage\":67.6,\"DressageLevel\":\"FIRST LEVEL, TEST 2\";}]}
}

The DisciplineData is the nested object. I am not familiar with the backslashes. And have done some research to see that it is "serializing".

This is the current code:

var elements = new UploadClassParameters 
{
    CompYear = 2025,
    CompID = 1234,
    ClassNumber = "12",
    Results = new List<Result> 
    { 
        new Result 
        {
            Placing = "1",
            HorseID = 4567,
            DisciplineData = new Dressage 
            {
                TotalScore = 169.0,
                TotalPercent = 67.600,
                DressageLevel = "FIRST LEVEL, TEST 2",
            } 
        } 
    }, 
};

string jsonPayload = Newtonsoft.Json.JsonConvert.SerializeObject(elements);
string signature = CreateSignature(clientID, clientSecret);

using (var client = new HttpClient()) 
{
       client.BaseAddress = new Uri("https://api.XXXXXX.org"); //  API endpoint

       // client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
       client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", signature);

       var content = new StringContent(jsonPayload, System.Text.Encoding.UTF8, "application/json");

       HttpResponseMessage response = await client.PostAsync("/api/results/uploadclass", content); 
}
New contributor
DukeStar is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1
  • This means the nested object, DisciplineData, is serialized as the value of a string field, which in turn contains a JSON object serialized as string. Use JSonConvert.Serialize/Deserialize to convert from object to string and vice versa. Commented 3 hours ago

1 Answer 1

0

As per Internal Server's comment, it looks like a double-serialization, though the OP's example appears to be missing the quotes around the serialized DisciplineData which would look more like:

      "DisciplineData":"{\"TotalScore\":169.0,\"TotalPercentage\":67.6,\"DressageLevel\":\"FIRST LEVEL, TEST 2\";}]}"

... with the extra \" string formatting within the overall string value. Often within APIs they will serialized sub-objects as JSON strings within the parent-level object, and a general naming convention for this is with the "Data" suffix.

public class Result
{ 
    public string Placing { get; set; }
    public int HorseID { get; set; }
    public string? DisciplineData  { get; private set; }
    [JsonIgnore]
    public Dressage? Dressage // or Discipline
    {
        get => field ??= !string.IsNullOrEmpty(DisciplineData)
            ? JsonConvert.DeserializeObject<Dressage>(DisciplineData)
            : null;
        set 
        {
           field = value;
           DisciplineData = value != null 
               ? JsonConvert.SerializeObject(value)
               : null;
        }
    }
   
}

Note: If not using C# 9 with preview language features or greater, field may not be recognized. A private Dressage? _dresssage; member can be substituted in that case.

The Dressage property is optional if you want to access the discipline data as the class type, otherwise just set the DiciplineData string as the serialized JSON with a public setter and deserialize as needed.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.