Answered by:
Blazor Server - deserializing an array of objects with System.Text.Json - The JSON value could not be converted to .....

Question
-
User379720387 posted
The JSON value could not be converted to BtServer.Pages.RecordDetail+MyRecordDetails. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, Type returnType, JsonSerializerOptions options)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, Type returnType, JsonSerializerOptions options)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at BtServer.Pages.RecordDetail.<OnInitializedAsync>d__12.MoveNext() in C:\Users\Robert\source\Repos\BtApiCore5\BtServer\Pages\RecordDetail.razor:line 92public class MyRecordDetails { public IEnumerable<RecordDetail> details { get; set; }
//tried this one too! same error message: public List<RecordDetail> details { get; set; } } protected override async Task OnInitializedAsync() { try { var httpClient = _clientFactory.CreateClient("ServerAPI"); httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); var json = JsonSerializer.Serialize(recordDetails); var content = new StringContent(json); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; HttpResponseMessage response = await httpClient.GetAsync($"{baseUrl}/api/Record/DetailByClient/22/49/3"); string dtls = await response.Content.ReadAsStringAsync(); if (dtls is not null) { MyRecordDetails details = JsonSerializer.Deserialize<MyRecordDetails>(dtls, options); } else { //do something } } catch (Exception ex) { Console.WriteLine(ex.Message); } }dtls holds:
[
{"TransactionId":1015,"CName":"Don","TDate":"May 9 2020 4:54PM","BDate":"May 9 2020 4:54PM","Initials":"JMC","IsBilled":false,"IsPaid":false,"SvcLevel":"R1"},
{"TransactionId":988,"CName":"Don","TDate":"Jan 23 2020 3:13PM","BDate":"Mar 10 2020 11:17AM","Initials":"JMC","IsBilled":false,"IsPaid":false,"SvcLevel":"R1"},
{"TransactionId":974,"CName":"Don","TDate":"Jan 22 2020 2:36PM","BDate":"Jan 22 2020 2:36PM","Initials":"JMC","IsBilled":false,"IsPaid":false,"SvcLevel":"R1"}
]Online deserializers have no problem deserializing dtls
public class RecordDetail { public int TransactionId { get; set; } public string CName { get; set; } public string TDate { get; set; } public string BDate { get; set; } public string Initials { get; set; } public bool IsBilled { get; set; } public bool IsPaid { get; set; } public string SvcLevel { get; set; } //public List<ServiceItem> ServiceItems { get; set; } //public List<ShoeItem> ShoeItems { get; set; } //public List<FileItem> FileItems { get; set; } //public List<ImageItem> ImageItems { get; set; } //public List<NoteItem> NoteItems { get; set; } //public List<VoiceItem> VoiceItems { get; set; } }
What am I doing wrong?
Sunday, March 7, 2021 2:20 PM
Answers
-
User-943250815 posted
Here is what I did:
1) Place your JSON sample above in a text file
2) Make a file with your class and a routine to read file and deserialize JSON into a Listpublic class RecordDetail { public int TransactionId { get; set; } public string CName { get; set; } public string TDate { get; set; } public string BDate { get; set; } public string Initials { get; set; } public bool IsBilled { get; set; } public bool IsPaid { get; set; } public string SvcLevel { get; set; } } void ReadJSonFromFile() { string MyFile = @"C:\sample.json"; string MyJsonStr = System.IO.File.ReadAllText(MyFile); List<RecordDetail> DetailsNoOptions = System.Text.Json.JsonSerializer.Deserialize<List<RecordDetail>>(MyJsonStr); var options = new System.Text.Json.JsonSerializerOptions() {PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase}; List<RecordDetail> DetailsWithOptions = System.Text.Json.JsonSerializer.Deserialize<List<RecordDetail>>(MyJsonStr, options);
}This results:
DetailsNoOptions = 3 itens, data filled with values from Json;
DetailsWithOptions = 3 itens, data filled with null- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, March 8, 2021 10:53 PM
All replies
-
User-943250815 posted
Back to your original intention, collect to a List.
Give a try to, your as is looks fine for a single record, but you are readind an arrayList<MyRecordDetails> details = JsonSerializer.Deserialize<List<MyRecordDetails>>(dtls, options);
Sunday, March 7, 2021 3:09 PM -
User379720387 posted
List<MyRecordDetails> details = JsonSerializer.Deserialize<List<MyRecordDetails>>(dtls, options);
Returns details which has 3 members, each of them null
Sunday, March 7, 2021 3:37 PM -
User-474980206 posted
You don’t show the class definition of MyRecordDetails
Sunday, March 7, 2021 4:38 PM -
User379720387 posted
@bruce (sqlwork)
This is all I have for MyRecordDetails, don't know if I am missing something:
public class MyRecordDetails { public IEnumerable<RecordDetail> details { get; set; } }
Sunday, March 7, 2021 4:46 PM -
User-943250815 posted
Oops, I mistyped my sample above, here the correct one, using it you should get a list with 3 elements and values filled correctly.
But don´t use "options" other than values will not be filledList<RecordDetail> details = JsonSerializer.Deserialize<List<RecordDetail>>(dtls);
Monday, March 8, 2021 11:51 AM -
User753101303 posted
Hi,
Or
MyRecordDetails details = new MyRecordDetails();details.details=JsonSerializer.Deserialize<List<RecordDetail>>(dtls);
Your json is a list of RecordDetail and you are confusing this with MyRecordDetails which is a single object having a property which is a list of RecordDetail and which is perhaps not needed.
.
Monday, March 8, 2021 1:53 PM -
User379720387 posted
@jzero
Without "options" it hangs and there are no exceptions shown in VS or in browser console
@PatriceSc
That maybe so, I don't know. Nothing works at this point, just throwing code on the wall and hope something sticks. So far I have been able to produce 3 elements (which matches what it is supposed to find) but each element is null.
Monday, March 8, 2021 9:53 PM -
User-943250815 posted
Here is what I did:
1) Place your JSON sample above in a text file
2) Make a file with your class and a routine to read file and deserialize JSON into a Listpublic class RecordDetail { public int TransactionId { get; set; } public string CName { get; set; } public string TDate { get; set; } public string BDate { get; set; } public string Initials { get; set; } public bool IsBilled { get; set; } public bool IsPaid { get; set; } public string SvcLevel { get; set; } } void ReadJSonFromFile() { string MyFile = @"C:\sample.json"; string MyJsonStr = System.IO.File.ReadAllText(MyFile); List<RecordDetail> DetailsNoOptions = System.Text.Json.JsonSerializer.Deserialize<List<RecordDetail>>(MyJsonStr); var options = new System.Text.Json.JsonSerializerOptions() {PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase}; List<RecordDetail> DetailsWithOptions = System.Text.Json.JsonSerializer.Deserialize<List<RecordDetail>>(MyJsonStr, options);
}This results:
DetailsNoOptions = 3 itens, data filled with values from Json;
DetailsWithOptions = 3 itens, data filled with null- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, March 8, 2021 10:53 PM -
User379720387 posted
Ok, figured it out.
I have a "view model" called RecordDetail.cs, you have seen it in this thread, it lives in the Web API project.
I also have a RecordDetail.razor page, it lives in the Blazor Server project
When you declare this:
private List<RecordDetail> recorddetails;
It is making List<RecordDetails.blazor> apparently. That fails silently, there are no warnings about ambiguity.
Too many leaves up in the air, and focused on the wrong leaf (deserialization).
Thanks all for contributing taking some of these leaves out of the air.
Tuesday, March 9, 2021 3:43 AM