JSON.Net,AnonymousTypes和Dashes

时间:2015-02-28 23:03:15

标签: c# json json.net

在C#中,有效的变量名称不能包含短划线。但是在Json中,所有属性名称都基于字符串,因此在Cson中,被认为是C#变量名称的无效字符可能被认为是有效的。

我的问题是,在尝试反序列化为匿名类型时,JSON.Net如何处理在属性名称中包含Dash或其他无效数据,更重要的是,在匿名类型中如何替换无效字符?抓住它。

如果需要示例数据,我可以提供它,但坦率地说,只需在Json Property名称中添加一个Dash( - ),简而言之就是你的情况。

P.S:我无法改变Json本身,因为它是从API中消耗的。

2 个答案:

答案 0 :(得分:2)

您可以使用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包中存在此重载。< / em>的

答案 1 :(得分:1)

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

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