I want to call a httpClient Post method and put the JSON response, which is an array consisting 2 double and put them as respective field in an object. e.g. the response is:
[12345, 56789]
I want to put 12345
as newObject.firstPrice, and 56789
as newObject.secondPrice, and retrieve them to do some computation later on. However, I am not sure how to do it.
I have seen 2 ways of deserialising a JSON response on the internet.
1st example:
seems like I should create a newObject and use <IEnumerable<newObject>>
& for each
to do so?
But what should I put inside the {}
in for each
?
namespace ConsoleProgram
{
public class DataObject
{
public string Name { get; set; }
}
public class Class1
{
static void Main(string[] args)
{
// HTTP request goes here
if (response.IsSuccessStatusCode)
{
// **Deserialisation into the Dataobject?**
var dataObjects = response.Content.ReadAsAsync<IEnumerable<DataObject>>().Result;
foreach (var d in dataObjects)
{
Console.WriteLine("{0}", d.Name);
}
}
...
2nd example:
(taken from the question ReadAsAsync deserializing HttpResponseMessage result)
PI caseInfos = null;
try
{
string strasd = response.Content.ReadAsStringAsync().Result;
m_Logging.Log(SharedLib.LoggingMode.Prompt, "ReadAsStringAsync() result:{0}", strasd);
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(PI));
using (TextReader reader = new StringReader(strasd))
caseInfos = (PI)serializer.Deserialize(reader);
m_Logging.Log(SharedLib.LoggingMode.Prompt, "Deserializing caseInfos model succeeded...");
}
catch (Exception ex)
{
m_Logging.Log(SharedLib.LoggingMode.Error, "creating model failed, EXP:{0}", ex);
}
The 2nd way seems more complicated, may I ask is it even the correct way to go for?
CodePudding user response:
could be
if (response.IsSuccessStatusCode)
{
var json = response.Content.ReadAsStringAsync().Result;
List<double> data = JsonConvert.DeserializeObject<List<double>>(json);
// or
double[] data = JsonConvert.DeserializeObject<double[]>(json);
var firstPrice= data[0];
}
CodePudding user response:
Serge's answer works, but if you wanted to specifically convert those values into a object with FirstPrice
and SecondPrice
properties, you could deserialize to an IList<double>
and then create an object from the deserialized value (This assumes that you are getting exactly 2 double values back. You might need to do additional checks in any other situation)
public class Result
{
public Result()
{
}
public Result(double firstPrice, double secondPrice)
{
this.FirstPrice = firstPrice;
this.SecondPrice = secondPrice;
}
public double FirstPrice { get; set; }
public double SecondPrice { get; set; }
public static Result FromResponse(IList<double> values)
{
ArgumentNullException.ThrowIfNull(values);
return values.Count == 2
? new Result(values[0], values[1])
: throw new ArgumentException(nameof(values), "Expected 2 double values");
}
public override string ToString()
{
return $"{nameof(FirstPrice)}: {this.FirstPrice}, {nameof(SecondPrice)}: {this.SecondPrice}";
}
}
Then when you're handling the HttpResponseMessage
, you can pass the content to the static method.
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
var content = JsonSerializer.Deserialize<IList<double>>(responseContent);
var result = Result.FromResponse(content);
}