簡體   English   中英

JsonSerializer.DeserializeAsync<t> 沒有錯誤,沒有異常,沒有結果</t>

[英]JsonSerializer.DeserializeAsync<T> no error, no exception, no result

在 my.NET MAUI 應用程序中,我正在反序列化 http 響應:

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;
}

在這種特殊情況下,T 是 List 的類型,例如:

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;
    }
}

我有來自服務器的響應,結果是 200,響應中有內容,但是當行var result = await JsonSerializer.DeserializeAsync(stream, options); 時運行,沒有錯誤,沒有異常,沒有結果,代碼就停止了。

謝謝

更新:所以我嘗試了建議的

  • ReadAsStringAsync()
  • ReferenceHandler = ReferenceHandler.IgnoreCycles 沒有工作。

當我反序列化為字符串時,我得到以下 json 作為字符串:

[{"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á(1992 年 5 月 3 日出生) )是斯洛伐克女排運動員。她是斯洛伐克國家女排的一員。她參加了2019年歐洲女排錦標賽。","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ésel 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 étven zát Békéscsabán,majd két szezont húzott le Nyíregyházán。 csabaiakkal mindent megnyert, amit csak itthon lehetett:bajnokságban és a Magyar Kupában 是 két-két elsőséggel gazdagodott,emellett egy Közép-európai Liga elsőséget 是 begyűjtött。 一個 nyíregyháziakkal két alkalommal hódította el a Magyar Kupa-trófeát, és 2018-ban, illetve 2019-ben 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 újab állomásaként Kaposvárt választotta, így újra együtt dolgozhatott korábbi edzőjével, Sasa Nedeljkoviccsal。 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:"ni"id"2,"ni"id"position:" "name":"opposite"},"validateCommand":{},"hasErrors":false}]

更新 2:調用反序列化的方法:

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);
        }
    }

更新 3:我剛剛創建了一個控制台應用程序,以找出問題所在。 我得到一個例外:

System.Text.Json.JsonException:“S”是值的無效開頭。 路徑:$ | 行號:0 | BytePositionInLine:0.'。

'S' 不是,它類似於 $ sing,但它不是。

您應該添加 JsonSerializerOptions 參考處理程序

在這里你的解決方案

new JsonSerializerOptions
{
  ReferenceHandler = ReferenceHandler.IgnoreCycles
}

var result = await JsonSerializer.DeserializeAsync<T>(stream, new JsonSerializerOptions
    {
      ReferenceHandler = ReferenceHandler.IgnoreCycles
    });

忘記一個 stream

        using (var response = await client.PostAsync(api, requestContent))
        {       
                if (response.IsSuccessStatusCode)
                {
                var responseContent = await response.Content.ReadAsStringAsync();
                result = JsonConvert.DeserializeObject<T>(responseContent);
               } 
        }

您發布的 class 太復雜了,我確定沒有序列化代碼。 因此,我建議您使用在線工具創建像這樣的 DTO。 這個 DTO 非常簡短,但它正確地反序列化了您的 json 字符串。 在此之后,您可以嘗試將 map DTO 數據添加到您的類中。 或者更好的是你可以找到很多代碼示例,它展示了如何使用 DTO 作為實現 MVVM 模式的 class 的基礎 class

List<DTO> data = JsonConvert.DeserializeObject<List<DTO>>(json);

public partial class DTO
{
    [JsonProperty("id")]
    public long Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("webImageLink")]
    public Uri WebImageLink { get; set; }

    [JsonProperty("club")]
    public string Club { get; set; }

    [JsonProperty("birthday")]
    public string Birthday { get; set; }

    [JsonProperty("birthPlace")]
    public string BirthPlace { get; set; }

    [JsonProperty("weight")]
    public long Weight { get; set; }

    [JsonProperty("height")]
    public double Height { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("position")]
    public Position Position { get; set; }

    [JsonProperty("validateCommand")]
    public ValidateCommand ValidateCommand { get; set; }

    [JsonProperty("hasErrors")]
    public bool HasErrors { get; set; }
}

public partial class Position
{
    [JsonProperty("id")]
    public long Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }
}
public partial class ValidateCommand
{
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM