当SignalR序列化字典并将其发送给客户端时,为什么将Dictionary键的首字母转换为小写?

gaa*_*kam 5 dictionary case-sensitive lowercase asp.net-core-2.0 asp.net-core-signalr

这是从服务器发送到客户端的内容:

public class BattleHub : Hub
{
    public override async Task OnConnectedAsync()
    {
        await Clients.Client(Context.ConnectionId).SendAsync("ConfigurationInfo",
            new Dictionary<string, string> { { "WtF", "WtF" } });

        await base.OnConnectedAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是客户收到的:

{"wtF":"WtF"}
Run Code Online (Sandbox Code Playgroud)

如以下客户代码所示:

const battle_connection = new signalR.HubConnectionBuilder().withUrl("/battlehub").build()

battle_connection.on("ConfigurationInfo", (bigDict) => {
    window.alert(JSON.stringify(bigDict))
})
Run Code Online (Sandbox Code Playgroud)

注意到字典键的第一个字母的大小写有所变化吗?应该发送“ WtF”,但是发送“ wtF”。

为什么会这样?有什么办法可以防止呢?

奇怪的是,这仅发生在字典键上:如您所见,值保持不变。同样仅发送单个字符串,而不包装在字典中,不会导致首字母变为小写。一种List<string>也被正确发送。

所有键的所有字母的大小写在这里实际上都是有意义的,因此,如果将其中任何一个强制转换为小写,则会使应用程序出错!当然,尽管我们可以想到解决该问题的或多或少的丑陋方法,但是有什么方法可以在SignalR串行器中关闭此转换?

ASP .NET Core 2.1

aar*_*ron 11

为什么会这样?

“我们将camelCase用于JSON中的名称,因为它更适合JavaScript模式。”
aspnet / SignalR#1415(评论)

有什么办法可以防止呢?

...有没有办法在SignalR串行器中关闭此转换?

是。

services
    .AddSignalR()
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
    });
Run Code Online (Sandbox Code Playgroud)


Dus*_*iah 6

services.AddSignalR().AddJsonProtocol(options =>
{
   options.PayloadSerializerOptions.PropertyNamingPolicy = null;
});
Run Code Online (Sandbox Code Playgroud)

  • 这是 .NET 5.0 及以上版本的正确答案,因为 ContractResolver 不再是一个属性。 (2认同)