我有一个Web项目被配置成这样:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
但是,我希望字典键大小写保持不变。在Newtonsoft.Json
中有什么属性可以用来表示在序列化过程中我希望大小写保持不变吗?
public class SomeViewModel
{
public Dictionary<string, string> Data { get; set; }
}
发布于 2014-06-15 04:02:01
没有属性可执行此操作,但您可以通过自定义解析器来完成。
我看到您已经在使用CamelCasePropertyNamesContractResolver
了。如果从中派生新的解析器类并重写CreateDictionaryContract()
方法,则可以提供不更改键名的替代DictionaryKeyResolver
函数。
下面是您需要的代码:
class CamelCaseExceptDictionaryKeysResolver : CamelCasePropertyNamesContractResolver
{
protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
{
JsonDictionaryContract contract = base.CreateDictionaryContract(objectType);
contract.DictionaryKeyResolver = propertyName => propertyName;
return contract;
}
}
演示:
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大小写的,但是字典键保留了它们原来的大小写。
{
"anIntegerProperty": 42,
"htmlString": "<html></html>",
"dictionary": {
"WHIZbang": "1",
"FOO": "2",
"Bar": "3"
}
}
发布于 2016-11-22 01:35:10
Json.NET 9.0.1引入了NamingStrategy
类层次结构来处理这类问题。它提取了从契约解析器到单独的轻量级类的属性名称算法重映射的逻辑,该类允许控制字典键、显式指定的属性名称和扩展数据名 (在10.0.1中)是否被重新映射。
通过使用DefaultContractResolver
并将NamingStrategy
设置为CamelCaseNamingStrategy
实例,可以在JsonSerializerSettings.ContractResolver
中设置带有骆驼大小写的属性名和未修改的字典键的JSON。
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
。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
继承来创建自己的。
CamelCasePropertyNamesContractResolver
实例的CamelCasePropertyNamesContractResolver
也是可能的,但由于后者的在每种类型的所有实例之间共享合约信息。,如果应用程序尝试使用多个CamelCasePropertyNamesContractResolver
实例,则可能会产生意外的副作用。在DefaultContractResolver
中不存在这样的问题,因此当需要对套管逻辑进行任何定制时,使用起来更安全。发布于 2016-06-05 04:12:44
这是一个很好的答案。但是为什么不直接覆盖ResolveDictionaryKey
class CamelCaseExceptDictionaryResolver : CamelCasePropertyNamesContractResolver
{
#region Overrides of DefaultContractResolver
protected override string ResolveDictionaryKey(string dictionaryKey)
{
return dictionaryKey;
}
#endregion
}
https://stackoverflow.com/questions/24143149
复制相似问题