将Json对象反序列化为.Net时type,如果字段名称不匹配,我发现您可以使用修饰您type的属性[JsonProperty(PropertyName = "name")]
type
[JsonProperty(PropertyName = "name")]
对于几个不匹配的属性,这很好而且很花哨,但是有没有办法设置约定或规则?
杰森
{ "Job": [ { "Job #": "1", "Job Type": "A", } ] }
C#
[JsonProperty(PropertyName = "Job Type")] public string JobType { get; set; } [JsonProperty(PropertyName = "Job #")] public string JobNumber { get; set; }
我想知道有很多使用相似名称的字段,有没有办法告诉您设置规则以始终删除空格(EG:)Job Type -> JobType并替换#为Number(eg:)Job # -> JobNumber?
Job Type -> JobType
#
Number
Job # -> JobNumber
看起来自定义ContractResolver可能是唯一的解决方案,但是我似乎无法弄清楚如何使用它来抽取空格并将“#”替换为“ Number”。有人参考示例吗?
ContractResolver
或者,我希望有一个很好的简单解决方案被我忽略了。
PS也接受更好的标题建议。
假设您正在使用Json.NET 9.0.1或更高版本,则可以使用custom来完成NamingStrategy。举例来说,这里是基于一个SnakeCaseNamingStrategy和StringUtils.ToSnakeCase()詹姆斯·牛顿王:
NamingStrategy
SnakeCaseNamingStrategy
StringUtils.ToSnakeCase()
public class CustomNamingStrategy : NamingStrategy { public CustomNamingStrategy(bool processDictionaryKeys, bool overrideSpecifiedNames) { ProcessDictionaryKeys = processDictionaryKeys; OverrideSpecifiedNames = overrideSpecifiedNames; } public CustomNamingStrategy(bool processDictionaryKeys, bool overrideSpecifiedNames, bool processExtensionDataNames) : this(processDictionaryKeys, overrideSpecifiedNames) { ProcessExtensionDataNames = processExtensionDataNames; } public CustomNamingStrategy() { } protected override string ResolvePropertyName(string name) { return SpaceWords(name); } enum WordState { Start, Lower, Upper, NewWord } static string SpaceWords(string s) { // Adapted from StringUtils.ToSnakeCase() // https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Utilities/StringUtils.cs#L191 // // Copyright (c) 2007 James Newton-King // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. char wordBreakChar = ' '; if (string.IsNullOrEmpty(s)) { return s; } StringBuilder sb = new StringBuilder(); WordState state = WordState.Start; for (int i = 0; i < s.Length; i++) { if (s[i] == ' ') { if (state != WordState.Start) { state = WordState.NewWord; } } else if (char.IsUpper(s[i])) { switch (state) { case WordState.Upper: bool hasNext = (i + 1 < s.Length); if (i > 0 && hasNext) { char nextChar = s[i + 1]; if (!char.IsUpper(nextChar) && nextChar != ' ') { sb.Append(wordBreakChar); } } break; case WordState.Lower: case WordState.NewWord: sb.Append(wordBreakChar); break; } sb.Append(s[i]); state = WordState.Upper; } else if (s[i] == wordBreakChar) { sb.Append(wordBreakChar); state = WordState.Start; } else { if (state == WordState.NewWord) { sb.Append(wordBreakChar); } sb.Append(s[i]); state = WordState.Lower; } } sb.Replace("Number", "#"); return sb.ToString(); } }
然后可以将其应用于您的类型,如下所示:
[JsonObject(NamingStrategyType = typeof(CustomNamingStrategy))] public class RootObject { public string JobType { get; set; } public string JobNumber { get; set; } public int JobItemCount { get; set; } public string ISOCode { get; set; } public string SourceXML { get; set; } }
并且生成的JSON将如下所示:
{ "Job Type": "job type", "Job #": "01010101", "Job Item Count": 3, "ISO Code": "ISO 9000", "Source XML": "c:\temp.xml" }
笔记:
如果要将策略应用于已通过指定属性名称的属性JsonPropertyAttribute.PropertyName,请设置NamingStrategy.OverrideSpecifiedNames == true。
JsonPropertyAttribute.PropertyName
NamingStrategy.OverrideSpecifiedNames == true
要将命名策略应用于所有类型而不是在每个对象上进行设置,可以在中设置命名策略DefaultContractResolver.NamingStrategy,然后在中设置合同解析器JsonSerializerSettings.ContractResolver。
DefaultContractResolver.NamingStrategy
JsonSerializerSettings.ContractResolver
命名策略从c#属性名称映射到JSON属性名称,反之亦然。因此,您需要插入空格,而不是“拔出”并将“ Number”替换为“#”。然后由合同解析器缓存该映射,并在反序列化过程中进行反向查找。