In my NET MAUI application I am de-serializing a http response:
private async Task<T> SerializeResponse<T>(HttpContent content)
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
using var stream = await content.ReadAsStreamAsync();
var result = await JsonSerializer.DeserializeAsync<T>(stream, options);
return result;
}
In this special case T is type of List, like:
public partial class BaseViewModel : ObservableValidator
{
public event NotifyWithValidationMessages? ValidationCompleted;
public virtual ICommand ValidateCommand => new RelayCommand(() => ValidateModel());
public BaseViewModel()
{
}
[IndexerName("ErrorDictionary")]
public ValidationStatus this[string propertyName]
{
get
{
ValidateAllProperties();
var errors = this.GetErrors()
.ToDictionary(k => k.MemberNames.First(), v => v.ErrorMessage) ?? new Dictionary<string, string?>();
var hasErrors = errors.TryGetValue(propertyName, out var error);
return new ValidationStatus(hasErrors, error ?? string.Empty);
}
}
public void ValidateModel()
{
ValidateAllProperties();
var validationMessages = this.GetErrors()
.ToDictionary(k => k.MemberNames.First().ToLower(), v => v.ErrorMessage);
ValidationCompleted?.Invoke(validationMessages);
}
}
public partial class PlayerModel : BaseViewModel
{
private int id;
private string name;
private string webImageLink;
private string club;
private string birthday;
private string birthPlace;
private int? weight;
private double? height;
private string description;
private PositionModel position;
public int Id
{
get => this.id;
set => SetProperty(ref this.id, value, true);
}
[Required]
[StringLength(255)]
[MinLength(2)]
public string Name
{
get => this.name;
set
{
SetProperty(ref this.name, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[Name]");
}
}
[Required]
[StringLength(4096)]
public string WebImageLink
{
get => this.webImageLink;
set
{
SetProperty(ref this.webImageLink, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[WebImageLink]");
}
}
[Required]
[StringLength(255)]
[MinLength(2)]
public string Club
{
get => this.club;
set
{
SetProperty(ref this.club, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[Club]");
}
}
[Required]
[StringLength(32)]
public string Birthday
{
get => this.birthday;
set
{
SetProperty(ref this.birthday, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[Birthday]");
}
}
[Required]
[StringLength(255)]
public string BirthPlace
{
get => this.birthPlace;
set
{
SetProperty(ref this.birthPlace, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[BirthPlace]");
}
}
[Required]
[Range(0, 100)]
public int? Weight
{
get => this.weight;
set
{
SetProperty(ref this.weight, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[Weight]");
}
}
[Required]
[Range(0, 2.5)]
public double? Height
{
get => this.height;
set
{
SetProperty(ref this.height, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[Height]");
}
}
[Required]
public string Description
{
get => this.description;
set
{
SetProperty(ref this.description, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[Description]");
}
}
[Required]
public PositionModel Position
{
get => this.position;
set
{
SetProperty(ref this.position, value, true);
ClearErrors();
ValidateAllProperties();
OnPropertyChanged("ErrorDictionary[Position]");
}
}
public PlayerModel() : base()
{
}
public PlayerModel(int id, string name, string webImageLink, string club, string birthday, string birthPlace, int weight, double height, string description, string positionName, int positionId) : base()
{
Id = id;
Name = name;
WebImageLink = webImageLink;
Club = club;
Birthday = birthday;
BirthPlace = birthPlace;
Weight = weight;
Height = height;
Description = description;
Position = new PositionModel(positionId, positionName);
}
public PlayerModel(int id, string name, string webImageLink, string club, string birthday, string birthPlace, int weight, double height, string description, PositionModel position) : base()
{
Id = id;
Name = name;
WebImageLink = webImageLink;
Club = club;
Birthday = birthday;
BirthPlace = birthPlace;
Weight = weight;
Height = height;
Description = description;
Position = position;
}
public PlayerModel(PlayerEntity player)
{
Id = player.Id;
Name = player.Name;
WebImageLink = player.WebImageLink;
Club = player.Club;
Birthday = player.Birthday;
BirthPlace = player.BirthPlace;
Weight = player.Weight;
Height = player.Height;
Description = player.Description;
Position = new PositionModel(player.Position);
}
public PlayerEntity ToEntity()
{
return new PlayerEntity
{
Id = Id,
Name = Name,
WebImageLink = WebImageLink,
Club = Club,
Birthday = Birthday,
BirthPlace = BirthPlace,
Weight = Weight.Value,
Height = Height.Value,
Description = Description,
PositionId = Position.Id
};
}
public void ToEntity(PlayerEntity player)
{
player.Id = Id;
player.Name = Name;
player.WebImageLink = WebImageLink;
player.Club = Club;
player.Birthday = Birthday;
player.BirthPlace = BirthPlace;
player.Weight = Weight.Value;
player.Height = Height.Value;
player.Description = Description;
player.PositionId = Position.Id;
}
}
I have a response from the server, the result is 200, there is content in the response, but when the line var result = await JsonSerializer.DeserializeAsync(stream, options); runs, no errors, no exception, no result, the code just stops.
thnx
UPDATE: So I tried the suggested
- ReadAsStringAsync()
- ReferenceHandler = ReferenceHandler.IgnoreCycles none worked.
When I deserialize to string, I got the following json as string:
[{"id":1,"name":"Nikola Radosová","webImageLink":"https://d3t3ozftmdmh3i.cloudfront.net/production/podcast_uploaded_episode/1378584/1378584-1567610413757-54d2f2d5dc6be.jpg","club":"FATUM Nyíregyháza","birthday":"1992.05.03","birthPlace":"Bojnice, Czechoslovakia","weight":66,"height":1.86,"description":"Nikola Radosová (born 3 May 1992) is a Slovak female volleyball player. She is part of the Slovakia women's national volleyball team. She competed at the 2019 Women's European Volleyball Championship.","position":{"id":1,"name":"outside hitter"},"validateCommand":{},"hasErrors":false},{"id":2,"name":"Tanja Matic","webImageLink":"https://brse.hu/wp-content/uploads/2022/07/Tanja-vote.jpg","club":"1. MCM-Diamant","birthday":"1983.03.21","birthPlace":"Subotica, Szerbia","weight":57,"height":1.79,"description":"Tanja Matic több száz szerb élvonalbeli mérkőzéssel a háta mögött, a patinás Szpartak Szabadka korábbi csapatkapitányaként 2015 nyarán érkezett hazánkba, és előbb két éven át játszott Békéscsabán, majd két szezont húzott le Nyíregyházán. A csabaiakkal mindent megnyert, amit csak itthon lehetett: a bajnokságban és a Magyar Kupában is két-két elsőséggel gazdagodott, emellett egy Közép-európai Liga elsőséget is begyűjtött. A nyíregyháziakkal két alkalommal hódította el a Magyar Kupa-trófeát, és 2018-ban, illetve 2019-ben is bejutott a bajnokság döntőjébe, ahol végül ezüstéremmel zárt. A tapasztalt röplabdázó ezek után, pályafutásának újabb állomásaként Kaposvárt választotta, így újra együtt dolgozhatott korábbi edzőjével, Sasa Nedeljkoviccsal. A 2019/2020-as évadban elért eredményekre mindenki büszke lehet, de mivel az ismert okok miatt váratlanul félbeszakadt, majd véget is ért a pontvadászat, mindenki kettőzött erővel szeretne majd újra munkába állni","position":{"id":2,"name":"opposite"},"validateCommand":{},"hasErrors":false}]
UPDATE 2: The method that calls deserialization:
protected async Task<T> SendGetRequestAsync<T>(string route, object routParam)
{
try
{
var uri = BuildUri(route, routParam);
var response = await httpClient.GetAsync(uri);
response.EnsureSuccessStatusCode();
var content = await SerializeResponse<T>(response.Content);
return content;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
UPDATE 3: I just created a single console app, to find out what is wrong. I am getting an exception:
System.Text.Json.JsonException: ''S' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.'.
The 'S' is not is, its something like $ sing, but it's not.