首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在序列化字典时保持大小写

在序列化字典时保持大小写
EN

Stack Overflow用户
提问于 2014-06-10 14:07:36
回答 4查看 28.7K关注 0票数 103

我有一个Web项目被配置成这样:

代码语言:javascript
运行
复制
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

但是,我希望字典键大小写保持不变。在Newtonsoft.Json中有什么属性可以用来表示在序列化过程中我希望大小写保持不变吗?

代码语言:javascript
运行
复制
public class SomeViewModel
{
    public Dictionary<string, string> Data { get; set; }    
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-15 04:02:01

没有属性可执行此操作,但您可以通过自定义解析器来完成。

我看到您已经在使用CamelCasePropertyNamesContractResolver了。如果从中派生新的解析器类并重写CreateDictionaryContract()方法,则可以提供不更改键名的替代DictionaryKeyResolver函数。

下面是您需要的代码:

代码语言:javascript
运行
复制
class CamelCaseExceptDictionaryKeysResolver : CamelCasePropertyNamesContractResolver
{
    protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
    {
        JsonDictionaryContract contract = base.CreateDictionaryContract(objectType);

        contract.DictionaryKeyResolver = propertyName => propertyName;

        return contract;
    }
}

演示:

代码语言:javascript
运行
复制
class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo
        {
            AnIntegerProperty = 42,
            HTMLString = "<html></html>",
            Dictionary = new Dictionary<string, string>
            {
                { "WHIZbang", "1" },
                { "FOO", "2" },
                { "Bar", "3" },
            }
        };

        JsonSerializerSettings settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCaseExceptDictionaryKeysResolver(),
            Formatting = Formatting.Indented
        };

        string json = JsonConvert.SerializeObject(foo, settings);
        Console.WriteLine(json);
    }
}

class Foo
{
    public int AnIntegerProperty { get; set; }
    public string HTMLString { get; set; }
    public Dictionary<string, string> Dictionary { get; set; }
}

这是上面的输出。注意,所有的类属性名称都是camel大小写的,但是字典键保留了它们原来的大小写。

代码语言:javascript
运行
复制
{
  "anIntegerProperty": 42,
  "htmlString": "<html></html>",
  "dictionary": {
    "WHIZbang": "1",
    "FOO": "2",
    "Bar": "3"
  }
}
票数 142
EN

Stack Overflow用户

发布于 2016-11-22 01:35:10

Json.NET 9.0.1引入了NamingStrategy类层次结构来处理这类问题。它提取了从契约解析器到单独的轻量级类的属性名称算法重映射的逻辑,该类允许控制字典键显式指定的属性名称扩展数据名 (在10.0.1中)是否被重新映射。

通过使用DefaultContractResolver并将NamingStrategy设置为CamelCaseNamingStrategy实例,可以在JsonSerializerSettings.ContractResolver中设置带有骆驼大小写的属性名和未修改的字典键的JSON。

代码语言:javascript
运行
复制
var resolver = new DefaultContractResolver
{
    NamingStrategy = new CamelCaseNamingStrategy
    {
        ProcessDictionaryKeys = false,
        OverrideSpecifiedNames = true
    }
};
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = resolver;

备注:

  • CamelCasePropertyNamesContractResolver的当前实现还指定了具有显式指定属性名的.Net成员(例如,已经设置了JsonPropertyAttribute.PropertyName的属性名称)应该进行名称映射: 公共CamelCasePropertyNamesContractResolver() { NamingStrategy =新CamelCaseNamingStrategy { ProcessDictionaryKeys = true,OverrideSpecifiedNames = true };} 上面的resolver保留了这种行为。如果您不想这样做,请设置OverrideSpecifiedNames = false
  • Json.NET有几个内置的命名策略,包括:
代码语言:javascript
运行
复制
1. [`CamelCaseNamingStrategy`](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_CamelCaseNamingStrategy.htm).  A camel case naming strategy that contains the name-remapping logic formerly embedded in `CamelCasePropertyNamesContractResolver`.
2. [`SnakeCaseNamingStrategy`](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_SnakeCaseNamingStrategy.htm).  A [snake case](https://en.wikipedia.org/wiki/Snake_case) naming strategy. 
3. [`DefaultNamingStrategy`](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_DefaultNamingStrategy.htm).  The default naming strategy. Property names and dictionary keys are unchanged. 

或者,您可以通过从抽象基类NamingStrategy继承来创建自己的。

票数 80
EN

Stack Overflow用户

发布于 2016-06-05 04:12:44

这是一个很好的答案。但是为什么不直接覆盖ResolveDictionaryKey

代码语言:javascript
运行
复制
class CamelCaseExceptDictionaryResolver : CamelCasePropertyNamesContractResolver
    {
        #region Overrides of DefaultContractResolver

        protected override string ResolveDictionaryKey(string dictionaryKey)
        {
            return dictionaryKey;
        }

        #endregion
    }
票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24143149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档