aspnetcore: HttpClient.PostJsonAsync deserialize json failed
Describe the bug
When I use below code in razor page to post a http request. The deserialized object is not correct. There is no exception happened.
billInfo = await Http.PostJsonAsync<BillInfo>("api/TMobileBill", filePath);
I then changed to use Http.PostAsync to get the response string, then deserialize it by using Newtonsoft library. It works fine.
var myContent = Newtonsoft.Json.JsonConvert.SerializeObject(filePath);
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json");
var response = await Http.PostAsync("api/TMobileBill", byteContent);
var responseStr = await response.Content.ReadAsStringAsync();
billInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<BillInfo>(responseStr);
StateHasChanged();
The response json string in my problem is:
{"period":"May 09, 2019 - Jun 08, 2019","dueDate":"Jul 01, 2019","totalAmount":326.03,"billInfoPerPerson":[{"name":"A B","phonesInfo":[{"phoneNumber":"(425) 111-1111","planHost":false,"usage":4.84,"regularCharge":30.0,"otherCharge":0.0,"totalCharge":0.0},{"phoneNumber":"(425) 222-2222","planHost":false,"usage":5.48,"regularCharge":30.0,"otherCharge":0.0,"totalCharge":0.0}],"totalAmount":60.0},{"name":"C D","phonesInfo":[{"phoneNumber":"(425) 333-3333","planHost":false,"usage":1.08,"regularCharge":20.0,"otherCharge":0.0,"totalCharge":0.0},{"phoneNumber":"(425) 444-4444","planHost":false,"usage":1.47,"regularCharge":20.0,"otherCharge":0.0,"totalCharge":0.0}],"totalAmount":40.0},{"name":"E F","phonesInfo":[{"phoneNumber":"(425) 555-5555","planHost":false,"usage":1.05,"regularCharge":20.0,"otherCharge":28.03,"totalCharge":0.0},{"phoneNumber":"(425) 666-6666","planHost":false,"usage":2.15,"regularCharge":30.0,"otherCharge":0.0,"totalCharge":0.0}],"totalAmount":78.03},{"name":"G H","phonesInfo":[{"phoneNumber":"(425) 777-7777","planHost":false,"usage":1.52,"regularCharge":20.0,"otherCharge":17.5,"totalCharge":0.0},{"phoneNumber":"(425) 888-8888","planHost":true,"usage":5.27,"regularCharge":30.0,"otherCharge":20.5,"totalCharge":0.0}],"totalAmount":88.0},{"name":"I J","phonesInfo":[{"phoneNumber":"(425) 999-9999","planHost":false,"usage":3.67,"regularCharge":30.0,"otherCharge":0.0,"totalCharge":0.0},{"phoneNumber":"(425) 000-0000","planHost":false,"usage":3.05,"regularCharge":30.0,"otherCharge":0.0,"totalCharge":0.0}],"totalAmount":60.0}],"warning":"There are $3 account service fee. Make sure it is expected. "}
The corresponding class is:
public class PersonBillInfo
{
public string Name;
public List<PhoneBillInfo> PhonesInfo;
public float TotalAmount;
}
public class PhoneBillInfo
{
public string PhoneNumber;
public bool PlanHost;
public float Usage;
public float RegularCharge;
public float OtherCharge;
public float TotalCharge;
}
public class BillInfo
{
public string Period;
public string DueDate;
public float TotalAmount;
public IEnumerable<PersonBillInfo> BillInfoPerPerson;
public string Warning;
}
To Reproduce
Steps to reproduce the behavior:
- Using this version of ASP.NET Core ‘SDK 3.0.100-preview6-012264’
- Implement a controller action to respond the json string as above.
- From razor page, use below code to call the controller action.
var billInfo = Http.PostJsonAsync<BillInfo>("api/TMobileBill", filePath);
- Evaluate the billInfo object. All the members of billInfo object are null.
Expected behavior
The members of billInfo object have values.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 19 (9 by maintainers)
@yan0lovesha I believe the issue here is that System.Text.Json doesn’t support doing serialization with public fields. Can you try using public properties instead?
Here’s what I tried with the settings
PostAsJsonAsynccurrently uses and it works fine:I’d recommend filing an issue in https://github.com/dotnet/corefx/issues to consider adding support for public fields in a future release.
Since the DateTimeOffset within the JSON is not ISO 8601 compliant (it contains spaces), the
JsonSerializerthrows an exception (see below, at least on preview 7). If the contents ofPublishDatewas changed to""2019-05-17T16:19:34-08:00"", it works as expected (and the object is deserialized fully).cc @steveharter, @layomia
@pranavkm the JSON is coming from a file (wwwroot content) as shown in the example above. The JSON property names match the C# property names.