JsonSerializer.Deserialize返回空对象

toe95027  于 2023-04-22  发布在  其他
关注(0)|答案(2)|浏览(158)

我有一个webapi,它返回一些Json:

{"id":9,"businessName":"dummy","address":"pluto","products":[
{"id":762,"description":"Centralized needs-based website","price":1281.24,"stock":1600,"categories":[],"factory":null},
{"id":1027,"description":"Realigned 6th generation knowledge base","price":2398.16,"stock":19583,"categories":[],"factory":null},
{"id":1392,"description":"User-centric zero administration array","price":998.07,"stock":6124,"categories":[],"factory":null},
{"id":1800,"description":"Team-oriented reciprocal core","price":4422.95,"stock":17372,"categories":[],"factory":null},
{"id":2763,"description":"Sharable needs-based hierarchy","price":4122.98,"stock":17397,"categories":[],"factory":null},
{"id":6189,"description":"Re-engineered hybrid emulation","price":395.09,"stock":532,"categories":[],"factory":null}
]}

然后我尝试使用以下命令进行反序列化:

using var response = await _httpClient.GetAsync($"{GetApiRouteFromEntity(entity)}/{entity.GetId()}");
        response.EnsureSuccessStatusCode();
        var responseContent = await response.Content.ReadAsStringAsync();
        T? item = JsonSerializer.Deserialize<T>(responseContent);

但这会给我一个id为0的空Factory,所有其他属性都为null

  • 工厂.cs*
public class Factory : EntityBase
    {
        [DisplayName("ID")]
        public int Id { get; set; }

        [DisplayName("Nome Business")]
        public string? BusinessName { get; set; }

        [DisplayName("Indirizzo")]
        public string? Address { get; set; }

        [DisplayName("Prodotti")] 
        public virtual ICollection<Product> Products { get; set; }
        
        public override string ToString()
        {
            return $"[{Id}] {BusinessName}";
        }
    }
  • 产品.cs*
public class Product : EntityBase
    {
        [DisplayName("ID")]
        public int Id { get; set; }

        [DisplayName("Descrizione")]
        public string? Description { get; set; }

        [DisplayName("Prezzo")]
        public float Price { get; set; }

        [DisplayName("Magazzino")]
        public int Stock { get; set; }

        [DisplayName("Categorie")]
        public virtual ICollection<Category> Categories { get; set; }

        [DisplayName("Fabbrica")]
        public virtual Factory Factory { get; set; }

        public override string ToString()
        {
            return $"[{Id}] {Description}";
        }
    }
  • EntityBase.cs*
public abstract class EntityBase
    {
        public virtual object GetId()
        {
            return GetType().GetProperty("Id").GetValue(this);
        }
    }

我猜这是因为工厂的产品 prop 是空的,但idk如何解决这个问题

sxissh06

sxissh061#

JSON键都是 Camel 大小写,但类中的prop是用pascal大小写编写的。例如businessNameBusinessName。因此JsonSerializer无法匹配它们。
你可以像这样初始化序列化器,以忽略大小写的差异:

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
T? item = JsonSerializer.Deserialize<T>(responseContent, options);

更多信息请参见文档:https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-character-casing

ct3nt3jp

ct3nt3jp2#

关于docs
默认情况下,属性名称和字典键在JSON输出中保持不变,包括大小写。
您可以指定属性命名策略:

T? item = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});

所有JSON属性名称都使用camel大小写,或者使用包含正确名称的JsonPropertyNameAttibute标记所有需要的属性:

public class Factory : EntityBase
{
    [DisplayName("ID")]
    [JsonPropertyName("id")] // and so on
    public int Id { get; set; }
    ....
}

或者将JsonSerializerOptions.PropertyNameCaseInsensitive设置为true

相关问题