我有一个Web Api项目配置如下:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
Run Code Online (Sandbox Code Playgroud)
但是,我希望字典键的外壳保持不变.是否有任何属性Newtonsoft.Json我可以使用一个类来表示我希望在序列化期间套管保持不变?
public class SomeViewModel
{
public Dictionary<string, string> Data { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*ers 122
没有属性可以执行此操作,但您可以通过自定义解析程序来执行此操作.
我看到你已经在使用了CamelCasePropertyNamesContractResolver.如果从中派生新的解析程序类并重写该CreateDictionaryContract()方法,则可以提供DictionaryKeyResolver不更改键名称的替换函数.
以下是您需要的代码:
class CamelCaseExceptDictionaryKeysResolver : CamelCasePropertyNamesContractResolver
{
protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
{
JsonDictionaryContract contract = base.CreateDictionaryContract(objectType);
contract.DictionaryKeyResolver = propertyName => propertyName;
return contract;
}
}
Run Code Online (Sandbox Code Playgroud)
演示:
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; }
}
Run Code Online (Sandbox Code Playgroud)
这是上面的输出.请注意,所有类属性名称都是驼峰式的,但字典键保留了原始的外壳.
{
"anIntegerProperty": 42,
"htmlString": "<html></html>",
"dictionary": {
"WHIZbang": "1",
"FOO": "2",
"Bar": "3"
}
}
Run Code Online (Sandbox Code Playgroud)
dbc*_*dbc 59
Json.NET 9.0.1引入了NamingStrategy类层次结构来处理这类问题.它将属性名称的算法重新映射的逻辑从合同解析器提取到单独的轻量级类,该类允许控制是否重新映射字典键,显式指定的属性名称和扩展数据名称(在10.0.1中).
通过使用DefaultContractResolver和设置NamingStrategy实例,CamelCaseNamingStrategy您可以通过设置以下内容来生成带有驼峰属性名称和未修改字典键的JSON JsonSerializerSettings.ContractResolver:
var resolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = false,
OverrideSpecifiedNames = true
}
};
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = resolver;
Run Code Online (Sandbox Code Playgroud)
笔记:
当前的实现CamelCasePropertyNamesContractResolver还指定具有显式指定的属性名称的.Net成员(例如JsonPropertyAttribute.PropertyName已设置的属性名称)应重新映射其名称:
public CamelCasePropertyNamesContractResolver()
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = true,
OverrideSpecifiedNames = true
};
}
Run Code Online (Sandbox Code Playgroud)
以上resolver保留了这种行为.如果您不想这样,请设置OverrideSpecifiedNames = false.
Json.NET有几个内置的命名策略,包括:
CamelCaseNamingStrategy.一种驼峰案例命名策略,其中包含以前嵌入的名称重新映射逻辑CamelCasePropertyNamesContractResolver.SnakeCaseNamingStrategy.一个蛇的情况下命名策略.DefaultNamingStrategy.默认命名策略.属性名称和字典键保持不变.或者,您可以通过继承抽象基类来创建自己的类NamingStrategy.
虽然也可以修改NamingStrategy实例CamelCasePropertyNamesContractResolver,因为后者在每种类型的所有实例之间全局共享合同信息,如果您的应用程序尝试使用多个实例,这可能会导致意外的副作用CamelCasePropertyNamesContractResolver.没有这样的问题DefaultContractResolver,因此当需要任何自定义套管逻辑时使用它更安全.
Dmi*_*riy 11
这是一个非常好的答案.但为什么不覆盖ResolveDictionaryKey?
class CamelCaseExceptDictionaryResolver : CamelCasePropertyNamesContractResolver
{
#region Overrides of DefaultContractResolver
protected override string ResolveDictionaryKey(string dictionaryKey)
{
return dictionaryKey;
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19624 次 |
| 最近记录: |