我不确定如何寻求帮助,这有点不寻常,我同意,所以请原谅我。我将尝试解释如下:
•我使用POST消费JSON并获取动态对象。我需要将动态对象中的所有传入属性转换为大写。
•我使用的是 我认为 是一个有效的解决方案。我将JSON转换为字符串Dictionary,然后在将Key转换为Key.ToUpper()之后将值放入新字典中,然后将其反序列化为动态对象。
当前工作解决方案如下:
string _StrJSON = @"{""FIELDA"" : ""1234"",""fieldb"" : ""OtherValue""}";
var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(_StrJSON);
d.ContainsKey("FIELDB").Dump(); // returns false, obviously.
Dictionary<string, string> dr = new Dictionary<string, string>();
d.ToList().ForEach(r => dr.Add(r.Key.ToUpper(), r.Value));
dr.Dump("dr"); // FIELDA 1234 - FIELDB OtherValue
var a = JsonConvert.SerializeObject(dr);
a.Dump(); // {"FIELDA":"1234","FIELDB":"OtherValue"}
这很有效。
[编辑] 关于我的&#34; var&#34;以上和其他东西。我非常清楚什么是动态的,什么是不动的。 [/编辑]
到目前为止我所尝试的不工作如下:
namespace Newtonsoft.Json
{
/// <summary>
/// Converts JSON keys to uppercase.
/// </summary>
public class UppercaseContractResolver : Serialization.DefaultContractResolver
{
#region Methods.
#region Public Methods.
/// <summary>
/// Resolves property name for this JSON object.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
protected override string ResolvePropertyName(string key)
{
return key.ToUpper();
}
#endregion
#endregion
#region Constructors.
/// <summary>
/// Converts JSON keys to uppercase.
/// </summary>
public UppercaseContractResolver()
{
}
#endregion
}
/// <summary>
/// Wrapper for Newtonsoft.Json.JsonConvert for JSON keys as uppercase.
/// </summary>
public static class JsonConvertUpper
{
#region Members.
#endregion
#region Methods.
#region Public Methods.
/// <summary>
/// Tries to serialize specified object with JSON keys in upper case.
/// <para>e.g. "key":value should become "KEY":value by using this method.</para>
/// </summary>
/// <param name="value">Object.</param>
/// <returns></returns>
public static string SerializeObjectUpper(object value)
{
return JsonConvert.SerializeObject(value, new JsonSerializerSettings
{
ContractResolver = new UppercaseContractResolver()
});
}
/// <summary>
/// Tries to Deserialize specified object with JSON keys in upper case.
/// <para>e.g. "key":value should become "KEY":value by using this method.</para>
/// </summary>
/// <param name="strValue">String.</param>
/// <returns></returns>
public static object DeserializeObjectUpper(string strValue)
{
// DeserializeObject does not allow uppercase properties. So use SerializeObjectUpper and then deserialize.
var value = JsonConvert.DeserializeObject(strValue);
string strJSON = SerializeObjectUpper(value);
return JsonConvert.DeserializeObject(strJSON, new JsonSerializerSettings()
{
ContractResolver = new UppercaseContractResolver()
});
}
#endregion
#endregion
}
}
上面的方法调用是:
dynamic json = JsonConvertUpper.DeserializeObjectUpper(_StrJSON);
if (json.CTN== null)
{...}
[编辑] 请注意我没有类,因为JSON键必须被视为UPPERCASE,类和其他代码等都在ProperCase中。 [/编辑]
任何方式 内部 JsonConvert都可以吗?为了避免我的手动补丁?任何帮助表示赞赏。感谢。
答案 0 :(得分:1)
您的合同解析程序不起作用的原因是Json.NET的contract resolver定义了如何在序列化时将JSON映射到POCO的属性 - 但是当您反序列化为dynamic
时, Json.NET实际上并不是从POCO映射到POCO,而是直接从JSON构建JToken
层次结构,其成员implement IDynamicMetaObjectProvider
。即。
dynamic o = JsonConvert.DeserializeObject(strJSON);
和
dynamic o = JToken.Parse(strJSON);
是一样的。
鉴于这种情况,最简单的方法是在构建层次结构时将每个属性名称显式转换为大写,如下所示:
public static class JsonExtensions
{
public static JToken ParseUppercase(string json)
{
using (var textReader = new StringReader(json))
using (var jsonReader = new JsonTextReader(textReader))
{
return jsonReader.ParseUppercase();
}
}
public static JToken ParseUppercase(this JsonReader reader)
{
return reader.Parse(n => n.ToUpperInvariant());
}
public static JToken Parse(this JsonReader reader, Func<string, string> nameMap)
{
JToken token;
using (var writer = new RenamingJTokenWriter(nameMap))
{
writer.WriteToken(reader);
token = writer.Token;
}
return token;
}
}
class RenamingJTokenWriter : JTokenWriter
{
readonly Func<string, string> nameMap;
public RenamingJTokenWriter(Func<string, string> nameMap)
: base()
{
if (nameMap == null)
throw new ArgumentNullException();
this.nameMap = nameMap;
}
public override void WritePropertyName(string name)
{
base.WritePropertyName(nameMap(name));
}
// No need to override WritePropertyName(string name, bool escape) since it calls WritePropertyName(string name)
}
然后使用它:
dynamic json = JsonExtensions.ParseUppercase(_StrJSON);
示例fiddle。