簡體   English   中英

JsonSerializer.Deserialize 失敗

[英]JsonSerializer.Deserialize fails

考慮代碼...

using System;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
        int id = 9;
        string str = "{\"id\": " + id + "}";
        var u = JsonSerializer.Deserialize<User>(str);
        Console.WriteLine($"User ID: {u.Id}, Correct: {id == u.Id}");  // always 0/init/default value
    }
}


public class User {
    public int Id { get; set; }
}

為什么沒有將數據正確反序列化到User對象中? 我還通過DotNetFiddle驗證了該行為,以防它是我系統本地的問題。 不會拋出異常。

在我return Created("user", newUser)之后,我的實際實現是從[ApiController][HttpPost]操作中讀取的。 它是通過_httpClient.PostAsync在我的 MVC/Razor 項目中調用的。 Created返回到PostAsync調用時,我驗證了這些值是正確的,但無論如何,從響應正文解析的值僅包含默認值(實際 ID 是Guid )。

我最初認為這可能是與 UTF8 相關的問題,因為那是我發布到ApiControllerStringContent的編碼。 這里引用了 UTF8 反序列化,但我在從HttpContent的 IO.Stream 到ReadOnlySpanUtf8JsonReader時遇到了麻煩。

我在搜索時發現了這個項目,這讓我認為它應該可以按預期工作。

您的問題是System.Text.Json默認情況下區分大小寫,因此"id": 9 (全部小寫)未映射到Id屬性。 文檔

不區分大小寫的屬性匹配

默認情況下,反序列化會在 JSON 和目標對象屬性之間查找區分大小寫的屬性名稱匹配。 要更改該行為,請將JsonSerializerOptions.PropertyNameCaseInsensitive設置為true

注意: Web 默認不區分大小寫。

 var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, }; var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options);

所以你還需要這樣做:

var u = JsonSerializer.Deserialize<User>(str, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

演示小提琴#1在這里

(如果差異完全是由於駱駝大小寫而不是更一般的大小寫差異,您可以將序列化程序配置為使用駱駝大小寫,如tj此答案所示。)

您可以在 ASP.NET Core 3.0 中配置啟動時的選項,如如何在 asp.net core 3 中設置 json 序列化程序設置?

services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});

或者,您可以將[JsonPropertyName("id")]應用於您的模型:

public class User {
    [JsonPropertyName("id")]
    public int Id { get; set; }
}

演示小提琴#2在這里

感謝mr5 通過 chat 提出這是一個外殼問題

更改字符串以使用 TitleCase ("Id") 解決了這個問題。

我正在提交工單,其中一個可能相關的問題評論將我引向另一個問題,該問題導致文檔,其中有一個解決方案

var options = new JsonSerializerOptions();
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;

使用選項,解決問題...

string str = "{\"id\": " + id + "}";
var options = new JsonSerializerOptions();
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
var u = JsonSerializer.Deserialize<User>(str, options);

留下這一切,以防它幫助別人。

您還可以閱讀此 microsoft 文檔JSON Serialization ,對於配置,您可以使用以下內容:

JsonSerializerOptions _jsonOptions = new(JsonSerializerDefaults.Web);
var serialized = JsonSerializer.Serialize(data, _jsonOptions);
var deserialized = JsonSerializer.Deserialize<TEntity>(serialized , _jsonOptions);

JsonSerializerDefaults.Web它是一個預定義的枚舉設置,如“camelCase 值”、“不區分大小寫的屬性名稱”等,檢查這個JsonSerializerDefaults。? , 如果你想自定義你會在這里再次查看文檔

Startup.csConfigureServices

services.AddControllers()
        .AddJsonOptions(o => {
            o.JsonSerializerOptions.PropertyNamingPolicy=JsonNamingPolicy.CamelCase;
            o.PropertyNameCasInsensitive=true
        });

暫無
暫無

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

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