我希望能够使用CamelCasePropertyNameContractResolver,但对特定的属性名称重写它。为此,我使用JsonProperty属性。这很好,除非我选择的名字完全大写。有什么不对的地方吗?怎样才能避开它?
在下面的示例中,Bar在不使用CamelCasePropertyNameContractResolver时被序列化为"BAR",但在使用解析器时被序列化为"bar"。在这两种情况下,Foo和CamelCaseProperty都是正确序列化的。
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace ConsoleTester
{
class Program
{
static void Main(string[] args)
{
var foo = new FooBar {CamelCaseProperty = "test", Foo = "test", Bar = "test" };
var output = JsonConvert.SerializeObject(foo);
// output "CamelCaseProperty", "fOO", "BAR"
var output2 = JsonConvert.SerializeObject(foo, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
// output "camelCaseProperty", "fOO", "bar"
}
}
public class FooBar
{
public string CamelCaseProperty { get; set; }
[JsonProperty("fOO")]
public string Foo { get; set; }
[JsonProperty("BAR")]
public string Bar { get; set; }
}
}发布于 2018-02-06 21:24:38
你看到这个的原因是CamelCasePropertyNamesContractResolver被故意设计为覆盖字典键和显式设置属性名称的大小写,从参考源中可以看到这一点。
public CamelCasePropertyNamesContractResolver()
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = true,
OverrideSpecifiedNames = true
};
}如果您不想这样做,您可以使用几个选项来防止显式名称的大小写,而无需创建您自己的自定义契约解析器类型。
首先,可以使用带有的DefaultContractResolver进行序列化。
var settings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }
};
var output2 = JsonConvert.SerializeObject(foo, settings);这使得CamelCaseNamingStrategy.OverrideSpecifiedNames的默认值为false。
其次,如果您无法访问框架的契约解析器,可以在特定属性上设置JsonPropertyAttribute.NamingStrategyType = typeof(DefaultNamingStrategy),如下所示:
public class FooBar
{
public string CamelCaseProperty { get; set; }
[JsonProperty("fOO")]
public string Foo { get; set; }
[JsonProperty("BAR", NamingStrategyType = typeof(DefaultNamingStrategy))]
public string Bar { get; set; }
}第三,如果您希望整个对象忽略当前契约解析器的命名策略,则可以将[JsonObject(NamingStrategyType = typeof(TNamingStrategy))]应用于对象:
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class FooBar
{
public string CamelCaseProperty { get; set; }
[JsonProperty("fOO")]
public string Foo { get; set; }
[JsonProperty("BAR")]
public string Bar { get; set; }
}备注:
CamelCasePropertyNamesContractResolver实例的CamelCasePropertyNamesContractResolver也是可能的,但由于后者的在每种类型的所有实例之间共享合约信息。,如果应用程序尝试使用多个CamelCasePropertyNamesContractResolver实例,则可能会产生意外的副作用。在DefaultContractResolver中不存在这样的问题,因此当需要对套管逻辑进行任何定制时,使用起来更安全。DefaultContractResolver时,您可能希望缓存契约解析器获得最佳性能,因为它不会在每种类型的所有实例之间全局共享契约信息。发布于 2018-02-06 17:47:58
JsonProperty属性在使用ContractResolver时不被接受。
要解决这个问题,您可以做的是覆盖ContractResolver:
public class MyResolver : CamelCasePropertyNamesContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if(member.GetCustomAttribute<JsonPropertyAttribute>() is JsonPropertyAttribute jsonProperty)
{
property.PropertyName = jsonProperty.PropertyName;
}
return property;
}
}用你的救世主:
var output2 = JsonConvert.SerializeObject(foo, new JsonSerializerSettings { ContractResolver = new MyResolver() });https://stackoverflow.com/questions/48647650
复制相似问题