19

I have a Blazor WebAssembly App (ASP.Net Core Hosted, Progressive Web App) with the following logic:

Client:

protected override async Task OnInitializedAsync() {
    string token = await _loginService.GetToken();

    _http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

    var result = await _http.PostAsJsonAsync("api/api/getcalllogs", userCallsRequestFilters);

    if (result.IsSuccessStatusCode) {
        var morUserCallLogs = await result.Content.ReadFromJsonAsync < MorUserCallLogsResponse > ();

        await js.InvokeAsync < object > ("TestDataTablesAdd", "#example");
    } else {
        morUserCallLogs = new MorUserCallLogsResponse();
    }
}

Server: (Server side API I have the following code which works as expected:)

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class MorApiController : ControllerBase
...

[HttpPost("getcalllogs")]
public async Task<MorUserCallLogsResponse> GetCallLogs ([FromBody] MorUserCallsRequestFilters filters)
{
...
return result;

Server side controller API populates the model ok and when I inspect I see the following snap (*some values have been blanked out for security) enter image description here

Model: (My MorUserCallLogsResponse model looks like this:)

namespace MyNumberV2.Model
{
    public class MorUserCallLogsResponse
    {
        public MorUserCallLogsResponse()
        { 
            Calls = new List<MorCall>();
        }
        public string Error { get; set; }
        public bool IsSuccessfull { get; set; }
        public string userid;
        public string username;
        ...
        ...
        public List<MorCall> Calls { get; set; }
        public class MorCall
        {
            public string calldate2;
            public string timezone;
            ...
            ...
        }
    }
}

Back to blazor and when I try to read this returned object on the following line:

var morUserCallLogs = await result.Content.ReadFromJsonAsync<MorUserCallLogsResponse>();

My retrieved model looks like this: enter image description here

As you can see my retrieved model contains all all properties with 140 nested call object models, however all properties are NULL...

3
  • 2
    Classic JSON camelCase/PascalCase serialization/deserialization issue Commented Aug 26, 2020 at 8:18
  • @aguafrommars Dude, THANKS a TON, I had to make options for the json to be case insensitive, and pass it the ReadFromJsonAsync method var options = new JsonSerializerOptions() { Converters = { new JsonStringEnumConverter() }, PropertyNameCaseInsensitive = true }; I also added a converters for enums based on my need. Commented Jun 9, 2022 at 15:23
  • It may be better to use JsonSerializerDefaults.Web as the starting point: var options = new JsonSerializerOptions(JsonSerializerDefaults.Web); options.Converters.Add(new JsonStringEnumConverter()); Commented Jan 19, 2023 at 22:54

4 Answers 4

17

I have forgotten to add get; set; for ALL my model properties...

{ get; set; }

  public string Error { get; set; }
  public bool IsSuccessfull { get; set; }
  public string userid { get; set; }
  public string username { get; set; }
  .....
Sign up to request clarification or add additional context in comments.

4 Comments

OK, fields don't serialize, properties do.
there is a code snippet in VS for creating auto properties. Type prop and hit tab twice. I use that to create new properties.
Also, setters must be public. One of the reasons I still use Newtonsoft
My properties are public with { get; set; } and my object is still ending up with default values, so this didn't end up resolving the issue for me.
8

I had to use following from property annotation using System.Text.Json.Serialization

 [JsonPropertyName("access_token")]
 public string AccessToken { get; set; }

Comments

3

Mine was fixed by passing an options parameter to the ReadFromJsonAsync method, which would make the json to be case insensitive about the properties in the json, so in your case, it would look like this:

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
var result = await result.Content.ReadFromJsonAsync<MorUserCallLogsResponse>(options);

Comments

2

"api/api/getcalllogs" doesn't match [Route("api/[controller]")] and [HttpPost("getcalllogs")]

As I read it the Url should be "api/MorApi/getcalllogs"

But then again, that should produce a 404 or 400

1 Comment

Correct this was changed by mistake but only on stackoverflow, actual code reads: var result = await _http.PostAsJsonAsync("api/morapi/getcalllogs", userCallsRequestFilters);

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.