JSON.Net、匿名类型和破折号

JSON.Net, AnonymousTypes and Dashes

在 C# 中,有效的变量名不能包含破折号。但是在 Json 中,所有 属性 名称都是基于字符串的,因此对于 C# 变量名称来说,被认为是无效字符的字符在 Json.[=11= 中可能被认为是有效的]

我的问题是,当尝试反序列化为匿名类型时,JSON.Net 如何处理 属性 名称中的破折号或其他无效数据,更重要的是,您如何处理将匿名类型中的无效字符替换为捕获它。

如果需要示例数据,我可以提供,但坦率地说,只需在 Json 属性 名称中添加破折号 (-),您就可以简要了解我的情况。

P.S:我无法更改 Json 本身,因为它是从 API.

消耗的

对于 Json.Net,我建议查看动态而不是匿名 UI,它可以将您的数据反序列化为 ExpandoObject,这是一种行为类似于字典的动态类型 - 即类似于一个 JavaScript 对象。这将意味着允许的 属性 名称范围扩大,因为它们成为字典键而不是 .Net 属性。

有点喜欢:Deserialize a property as an ExpandoObject using JSON.NET

您可以使用 ContractResolver 来操纵 JSON.Net 如何将 C# 属性 名称映射到 JSON 名称。

对于您的示例,此代码执行此操作:

class DashContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        // Count capital letters
        int upperCount = propertyName.Skip(1).Count(x => char.IsUpper(x));
        // Create character array for new name
        char[] newName = new char[propertyName.Length + upperCount];
        // Copy over the first character
        newName[0] = char.ToLowerInvariant(propertyName[0]);

        // Fill the character, and an extra dash for every upper letter
        int iChar = 1;
        for (int iProperty = 1; iProperty < propertyName.Length; iProperty++)
        {
            if (char.IsUpper(propertyName[iProperty]))
            {
                // Insert dash and then lower-cased char
                newName[iChar++] = '-';
                newName[iChar++] = char.ToLowerInvariant(propertyName[iProperty]);
            }
            else
                newName[iChar++] = propertyName[iProperty];
        }

        return new string(newName, 0, iChar);
    }
}

class Program
{
    static void Main(string[] args)
    {
        string json = @"{""text-example"":""hello""}";
        var anonymous = new { textExample = "" };
        var obj = JsonConvert.DeserializeAnonymousType(json, anonymous,
            new JsonSerializerSettings
            {
                ContractResolver = new DashContractResolver()
            });


    }
}

它将UpperCamelCaselowerCamelCase转换为lower-dash-case。因此映射到您的 JSON 输入。

DeserializeAnonymousType 的这种重载并不总是可用,并且在 Visual Studio 2013 发布的版本中不可用。当前(稳定的)NuGet 包有这个超载。