C# 获取JsonConvert.DeserializeObject的动态对象,使属性大写

C# 获取JsonConvert.DeserializeObject的动态对象,使属性大写,c#,json,json.net,C#,Json,Json.net,我不知道如何寻求帮助,这是一种不寻常的我同意,所以请原谅我。我将试着解释如下: namespace Newtonsoft.Json { /// <summary> /// Converts JSON keys to uppercase. /// </summary> public class UppercaseContractResolver : Serialization.DefaultContractResolver { #region Methods.

我不知道如何寻求帮助,这是一种不寻常的我同意,所以请原谅我。我将试着解释如下:

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
}
}
•我使用POST使用JSON并获得动态对象。我需要将动态对象中的所有传入属性转换为大写

•我正在使用我认为是一种不切实际的解决方案。我将JSON转换为字符串字典,然后在将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"}
[编辑] 请注意,我没有类,因为JSON键必须被视为大写,而类和其他代码等都是用大写字母表示的。 [/编辑]


有没有办法在内部进行转换?为了避免我的手动补丁?感谢您的帮助。谢谢。

您的契约解析器无法工作的原因是,Json.NET定义了在序列化时如何将Json从POCO的属性映射到POCO的属性——但当您反序列化到
dynamic
时,Json.NET实际上并不是从POCO映射到POCO,而是直接从Json构建层次结构,其中的成员是。即

都是一样的

在这种情况下,最简单的方法是在构建层次结构时将每个属性名称显式转换为大写,如下所示:

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)
}

示例。

您可以使用类上的
JsonProperty
属性重命名道具。请注意,动态对象是在运行时确定的对象。这些不是动态类型。“var”变量是强类型变量。只是想澄清一下这里的术语是的,我知道,但我已经编辑了我的问题。啊@dbc绝对漂亮!非常感谢。:)今天早上我用JToken和JArray尝试了各种各样的循环,用于对象内部的数组。我用
字符串测试了小提琴{“FIELDA”:“1234”,“fieldb”:“OtherValue”,“ARRAYDATA”:[{“FIELD1”:“ArrayPropOne”,“ArrayInsideArray1”:[{“Fieldx”:“InsideArray1”,“ArrayInsideArray2”:[{“Fieldxy”:“InsideArray2”}]}]工作正常。非常感谢,非常感谢。
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);