我try 将[JsonPropertyName][ObservableProperty]结合起来,将json的值"last_updated"赋给对象的属性"Updated".

我试过这个代码:

[ObservableProperty]
[JsonPropertyName("last_updated")]
public string updated;

而是it is not working: 'Updated' is null after deserializing美元.

正确的处理方式应该是什么呢?

JSON的一个例子:

[{"id":1,"username":"******","password":"******","email":"*****","created":"2023-12-19 19:28:23","last_updated":"2023-12-19 19:28:23","address":"*******","full_name":"*******","last_login":{"id":1,"user_id":1,"ip_address":"******","result_code":"0","result":"Success"},"role":"Admin"}]

项目详情:

  • WinUI 3
  • System.Text.Json 8.0.0
  • 社区工具包.Mvvm 8.2.2
  • .NET 6.0

我添加了一个显示判断的屏幕截图:

Screenshot of debugger

完整的类代码:

using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace RotaPro.Models;

public partial class Dipendente : ObservableObject
{

    [ObservableProperty]
    private int id;

    [ObservableProperty]
    private string username;

    [ObservableProperty]
    private string email;

    [ObservableProperty]
    private string created;

    [ObservableProperty]
    [JsonPropertyName("last_updated")]
    public string updated;

    [ObservableProperty]
    private string address;

    [ObservableProperty]
    [JsonPropertyName("full_name")]
    private string fullName;

    public Dipendente()
    {

    }

    public Dipendente(int id, string username, string email, string created, string updated, string address, string fullName)
    {
        Id = id;
        Username = username;
        Email = email;
        Created = created;
        Updated = updated;
        Address = address;
        FullName = fullName;
    }

    public override string ToString()
    {
        return FullName;
    }

}

反序列化代码:

using Microsoft.UI.Xaml.Media.Animation;
using RestSharp;
using RestSharp.Authenticators;
using RotaPro.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.Json;
using System.Net;
using System.Net.Http;
using Serilog;

namespace RotaPro.Classes;

public class ApiClient
{

    private static RestClient _instance;
    private static bool _initialized = false;

    public ApiClient()
    {
        
    }

    public void Initialize(string username, string apiKey)
    {
        if (_instance is not null)
            throw new InvalidOperationException("ApiClient già inizializzato");

        RestClientOptions options = new RestClientOptions("https://*****/***/**/")
        {
            Authenticator = new HttpBasicAuthenticator(username, apiKey)
        };

        _instance = new RestClient(options);
        _initialized = true;
    }

    public static async Task<List<Dipendente>> GetDipendenti()
    {
        if (!_initialized)
            throw new InvalidOperationException("ApiClient non inizializzato");

        RestRequest request = new RestRequest("/user/all");
        RestResponse response = await _instance.ExecuteAsync(request);

        if(!response.StatusCode.Equals(HttpStatusCode.OK))
        {
            throw new HttpRequestException($"Errore {response.StatusCode} durante la richiesta");
        }

        string json = response.Content;
        Log.Debug($"Ricevuto: {json}");

        JsonSerializerOptions options = new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        };

        List<Dipendente> lista = JsonSerializer.Deserialize<List<Dipendente>>(json, options)!;

        return lista;
    }

}

推荐答案

问题是您试图使用两个对不同类型的类成员起作用的属性.

[ObservableProperty]源生成器为给定的field创建一个可观察属性.

[JsonPropertyName]属性使您可以通过通常用JSON属性修饰C#property来为JSON属性提供特定的名称(默认行为).

后者不起作用,因为您将其应用于一个字段,而它应该是一个属性.但是,您也不能将该字段更改为属性,因为这样源代码生成器就会发出编译器错误,因为它需要一个字段.

恐怕您不能将这两种方法与修改代码结合使用.

对于要用[JsonPropertyName]装饰的属性,可以使用classic 属性:

private string updated;

[JsonPropertyName("last_updated")]
public string Updated
{
    get => updated;
    set => SetProperty(ref updated, value);
}

或者:

[ObservableProperty]
private string updated;

[JsonPropertyName("last_updated")]
public string LastUpdated
{
    get => Updated;
    set => Updated = value;
}

后者允许您拥有另一个可观察的属性,该属性在设置LastUpdated属性时设置.

然而,请注意,我并没有看到这样做有什么真正的好处.这里的用例是什么?通常,JSON属性是DTO(数据传输对象)的一部分,这些值不会频繁更新.您可能需要考虑将您的类划分为DTO类和模型类.

Csharp相关问答推荐

使用其可能实现的基类和接口的属性的方法

如何修改中间件或其注册以正确使用作用域服务?

==和Tuple对象的相等<>

REST API端点中异步后台代码执行的类型

Blazor-从数据库内部服务器提取错误

为什么SignalR在每个Blazor服务器应用程序启动时最多启动8个服务器?

StackExchange.Redis.RedisServerException:调用ITransaction.ExecuteAsync()时出现错误未知命令取消监视

try 使用C#ASP.NET收集WMI信息时访问被拒绝,但在PowerShell中工作

在不添加不必要的尾随零的情况下本地化浮点型?

C#中浮点数的System.Text.Json序列化问题

什么时候接受(等待)信号灯?尽可能的本地化?

Selify只更改第一个下拉菜单,然后忽略REST-C#

使用switch 类型模式时出现奇怪的编译器行为

Postgres ENUM类型在第一次运行时对Dapper不可见

多个参数的最小API删除

数据库操作预计影响1行,但实际影响0行; after _dbContext.SaveChanges();

如何使用LINQ在C#中填充列表列表?

在C#和HttpClient中使用REST API

C#中的逻辑运算符用作单词';is';and';and';

GMap.NET中的暗模式映射