programing

ASP에서 JSON을 간단한 사전으로 역직렬화하려면 어떻게 해야 합니까?인터넷?

telecom 2023. 3. 26. 09:39
반응형

ASP에서 JSON을 간단한 사전으로 역직렬화하려면 어떻게 해야 합니까?인터넷?

JSON의 간단한 키/값 리스트를 ASP로 반송하고 있습니다.POST를 통한 NET. 예:

{ "key1": "value1", "key2": "value2"}

강력한 타입의 .NET 객체로 역직렬화하려는 것이 아닙니다.

그냥 일반 사전(Of String, String) 또는 동등한 것(해시 테이블, 사전(Of String, Object), 구식 String Dictionary--hell, 2D 배열의 문자열이 필요합니다.

ASP에서 사용할 수 있는 것은 무엇이든 사용할 수 있습니다.NET 3.5 및 인기 Json.NET(클라이언트로의 시리얼화에 이미 사용하고 있습니다).

이러한 JSON 라이브러리 중 어느 것도 이러한 기능을 바로 사용할 수 없는 것은 분명합니다. 즉, 강력한 계약을 통한 반사 기반 역직렬화에 완전히 초점을 맞추고 있습니다.

좋은 생각 있어요?

제한 사항:

  1. 독자적인 JSON 파서를 실장하고 싶지 않다
  2. ASP를 사용할 수 없습니다.NET 4.0은 아직
  3. 더 이상 사용되지 않는 오래된 ASP를 멀리하고 싶다.JSON용 NET 클래스

Json.NET이 이렇게...

string json = @"{""key1"":""value1"",""key2"":""value2""}";

var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

기타 예:Json을 사용하여 컬렉션을 직렬화합니다.네트워크

는는발발발발다다에는, 문자열을 에 하는 있습니다.Dictionary<String, Object> the를 System.Web.Script.Serialization.JavaScriptSerializer5 3.5 라고합니다.System.Web.Extensions방법DeserializeObject(String)

json 포스트(를했을 때 이 유형 '.net Page Method'의를 가진 메서드)가 '/'application/json' ajax'(jqueryObject처럼 이 을 받았습니다가 마법처럼 이 사전을 받았습니다.

System.Text.제이슨

이것으로, 에 짜넣어진 를 사용할 수 있게 되었습니다.NET Core 3.0서드파티 라이브러리를 사용하지 않고 JSON을 역직렬화할 수 있게 되었습니다.

var json = @"{""key1"":""value1"",""key2"":""value2""}";
var values = JsonSerializer.Deserialize<Dictionary<string, string>>(json);

NuGet 패키지 시스템에서도 사용할 수 있습니다.Text.Json(사용하는 경우)NET Standard 또는NET 프레임워크


다음 내용을 읽고 이해하십시오.

인터넷을 검색하다가 우연히 이 글을 보게 된 분들을 위해 JavaScriptSerializer 클래스 사용법에 대한 블로그 투고를 작성했습니다.

자세한 내용은 이쪽...http://procbits.com/2011/04/21/quick-json-serializationdeserialization-in-c/

다음은 예를 제시하겠습니다.

var json = "{\"id\":\"13\", \"value\": true}";
var jss = new JavaScriptSerializer();
var table = jss.Deserialize<dynamic>(json);
Console.WriteLine(table["id"]);
Console.WriteLine(table["value"]);

저도 같은 문제가 있어서 제가 직접 쓴 거예요.이 솔루션은, 복수의 레벨로 역직렬화할 수 있기 때문에, 다른 회답과는 다릅니다.

JSON 문자열을 전송하여 역직렬화하기만 하면 됩니다.ToDictionary 함수는 강하게 입력되지 않은 객체를 반환합니다.

구코드

private Dictionary<string, object> deserializeToDictionary(string jo)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
    var values2 = new Dictionary<string, object>();
    foreach (KeyValuePair<string, object> d in values)
    {
        // if (d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
        if (d.Value is JObject)
        {
            values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
        }
        else
        {
            values2.Add(d.Key, d.Value);
        }
    }
    return values2;
}

예: 반환됩니다.Dictionary<string, object>Facebook JSON ★★★★★★★★★★★★★★★★★★」

시험

private void button1_Click(object sender, EventArgs e)
{
    string responsestring = "{\"id\":\"721055828\",\"name\":\"Dasun Sameera Weerasinghe\",\"first_name\":\"Dasun\",\"middle_name\":\"Sameera\",\"last_name\":\"Weerasinghe\",\"username\":\"dasun\",\"gender\":\"male\",\"locale\":\"en_US\",  hometown: {id: \"108388329191258\", name: \"Moratuwa, Sri Lanka\",}}";
    Dictionary<string, object> values = deserializeToDictionary(responsestring);
}

은 주 a로 됩니다.Dictionary<string, object>★★★★★★ 。

갱신하다

JSON 문자열에 배열이 없으면 이전 답변이 잘 작동합니다.은 더 것, 층, 층, 층, 직, 직, this, this, this, this, this, this, this, this, this, this, 이다.List<object>요소가 배열인 경우.

JSON 문자열을 전송하여 역직렬화하십시오.ToDictionaryOrList 함수는 강하게 입력되지 않은 오브젝트 또는 를 반환합니다.

private static object deserializeToDictionaryOrList(string jo,bool isArray=false)
{
    if (!isArray)
    {
        isArray = jo.Substring(0, 1) == "[";
    }
    if (!isArray)
    {
        var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
        var values2 = new Dictionary<string, object>();
        foreach (KeyValuePair<string, object> d in values)
        {
            if (d.Value is JObject)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
            }
            else if (d.Value is JArray)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString(), true));
            }
            else
            {
                values2.Add(d.Key, d.Value);
            }
        }
        return values2;
    }else
    {
        var values = JsonConvert.DeserializeObject<List<object>>(jo);
        var values2 = new List<object>();
        foreach (var d in values)
        {
            if (d is JObject)
            {
                values2.Add(deserializeToDictionary(d.ToString()));
            }
            else if (d is JArray)
            {
                values2.Add(deserializeToDictionary(d.ToString(), true));
            }
            else
            {
                values2.Add(d);
            }
        }
        return values2;
    }
}

외부 JSON 실장을 사용하지 않기 위해 다음과 같이 역직렬화했습니다.

string json = "{\"id\":\"13\", \"value\": true}";

var serializer = new JavaScriptSerializer(); //using System.Web.Script.Serialization;

Dictionary<string, string> values = serializer.Deserialize<Dictionary<string, string>>(json);

네스트된 사전을 파싱하면 되는데

{
    "x": {
        "a": 1,
        "b": 2,
        "c": 3
    }
}

서 ''는JsonConvert.DeserializeObject같은 접근방식을 했다.하다

var dict = JObject.Parse(json).SelectToken("x").ToObject<Dictionary<string, int>>();

SelectToken을 사용법''와 같은 할 수 ."x.y.z"JSON 오브젝트로 이동합니다.

가볍고 레퍼런스가 추가되지 않은 접근방식을 원하신다면 방금 작성한 이 코드가 작동될 수 있습니다(단, 100% 견고성을 보장할 수는 없습니다).

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

public Dictionary<string, object> ParseJSON(string json)
{
    int end;
    return ParseJSON(json, 0, out end);
}
private Dictionary<string, object> ParseJSON(string json, int start, out int end)
{
    Dictionary<string, object> dict = new Dictionary<string, object>();
    bool escbegin = false;
    bool escend = false;
    bool inquotes = false;
    string key = null;
    int cend;
    StringBuilder sb = new StringBuilder();
    Dictionary<string, object> child = null;
    List<object> arraylist = null;
    Regex regex = new Regex(@"\\u([0-9a-z]{4})", RegexOptions.IgnoreCase);
    int autoKey = 0;
    for (int i = start; i < json.Length; i++)
    {
        char c = json[i];
        if (c == '\\') escbegin = !escbegin;
        if (!escbegin)
        {
            if (c == '"')
            {
                inquotes = !inquotes;
                if (!inquotes && arraylist != null)
                {
                    arraylist.Add(DecodeString(regex, sb.ToString()));
                    sb.Length = 0;
                }
                continue;
            }
            if (!inquotes)
            {
                switch (c)
                {
                    case '{':
                        if (i != start)
                        {
                            child = ParseJSON(json, i, out cend);
                            if (arraylist != null) arraylist.Add(child);
                            else
                            {
                                dict.Add(key, child);
                                key = null;
                            }
                            i = cend;
                        }
                        continue;
                    case '}':
                        end = i;
                        if (key != null)
                        {
                            if (arraylist != null) dict.Add(key, arraylist);
                            else dict.Add(key, DecodeString(regex, sb.ToString()));
                        }
                        return dict;
                    case '[':
                        arraylist = new List<object>();
                        continue;
                    case ']':
                        if (key == null)
                        {
                            key = "array" + autoKey.ToString();
                            autoKey++;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                        dict.Add(key, arraylist);
                        arraylist = null;
                        key = null;
                        continue;
                    case ',':
                        if (arraylist == null && key != null)
                        {
                            dict.Add(key, DecodeString(regex, sb.ToString()));
                            key = null;
                            sb.Length = 0;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                       continue;
                    case ':':
                        key = DecodeString(regex, sb.ToString());
                        sb.Length = 0;
                        continue;
                }
            }
        }
        sb.Append(c);
        if (escend) escbegin = false;
        if (escbegin) escend = true;
        else escend = false;
    }
    end = json.Length - 1;
    return dict; //theoretically shouldn't ever get here
}
private string DecodeString(Regex regex, string str)
{
    return Regex.Unescape(regex.Replace(str, match => char.ConvertFromUtf32(Int32.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.HexNumber))));
}

[오퍼레이션 제한 #1에 위반되는 건 알지만 엄밀히 말하면 네가 쓴 게 아니라 내가 쓴 거야]

Mark Rendle이 코멘트로 이 글을 올렸습니다.그것은 지금까지 성공과 Google reCaptcha 응답의 에러 코드 json 결과를 되돌리기 위한 유일한 솔루션이기 때문입니다.

string jsonReponseString= wClient.DownloadString(requestUrl);    
IDictionary<string, object> dict = new JavaScriptSerializer().DeserializeObject(jsonReponseString) as IDictionary<string, object>;

다시 한 번 고마워, 마크!

JSON을 사전으로 변환하려는 모든 사용자에게 적합합니다.를 사용하는 간단한 방법이 있습니다.Newtonsoft.JSON

using Newtonsoft.Json.Linq
...

JObject o = JObject.Parse(@"{
  'CPU': 'Intel',
  'Drives': [
    'DVD read/writer',
    '500 gigabyte hard drive'
  ]
}");

string cpu = (string)o["CPU"];
// Intel

string firstDrive = (string)o["Drives"][0];
// DVD read/writer

IList<string> allDrives = o["Drives"].Select(t => (string)t).ToList();
// DVD read/writer
// 500 gigabyte hard drive

JSnake04 다순이다. from i i브 i i i i 。JArray 된 유한 트리 에 대량의 이 없습니다.양방향 재귀가 있지만 고정된 유한 트리 모델에서 기능하기 때문에 대량의 데이터가 없는 한 스택 오버플로의 위험이 없습니다.

/// <summary>
/// Deserialize the given JSON string data (<paramref name="data"/>) into a
///   dictionary.
/// </summary>
/// <param name="data">JSON string.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(string data)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(data);

    return DeserializeData(values);
}

/// <summary>
/// Deserialize the given JSON object (<paramref name="data"/>) into a dictionary.
/// </summary>
/// <param name="data">JSON object.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(JObject data)
{
    var dict = data.ToObject<Dictionary<String, Object>>();

    return DeserializeData(dict);
}

/// <summary>
/// Deserialize any elements of the given data dictionary (<paramref name="data"/>) 
///   that are JSON object or JSON arrays into dictionaries or lists respectively.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(IDictionary<string, object> data)
{
    foreach (var key in data.Keys.ToArray()) 
    {
        var value = data[key];

        if (value is JObject)
            data[key] = DeserializeData(value as JObject);

        if (value is JArray)
            data[key] = DeserializeData(value as JArray);
    }

    return data;
}

/// <summary>
/// Deserialize the given JSON array (<paramref name="data"/>) into a list.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized list.</returns>
private IList<Object> DeserializeData(JArray data)
{
    var list = data.ToObject<List<Object>>();

    for (int i = 0; i < list.Count; i++)
    {
        var value = list[i];

        if (value is JObject)
            list[i] = DeserializeData(value as JObject);

        if (value is JArray)
            list[i] = DeserializeData(value as JArray);
    }

    return list;
}

편집: 이것은 작동하지만 Json을 사용하여 승인된 답변입니다.NET은 훨씬 더 간단합니다.누군가 BCL 전용 코드를 필요로 할 때를 대비해서 이걸 놔두는 거야

에서는 지원되지 않습니다.즉시 사용 가능한 NET 프레임워크.눈에 띄는 실수 – 누구나 명명된 속성을 가진 객체로 역직렬화할 필요는 없습니다.그래서 나는 결국 내 것을 굴리고 말았다.

VB.NET:

<Serializable()> Public Class StringStringDictionary
    Implements ISerializable
    Public dict As System.Collections.Generic.Dictionary(Of String, String)
    Public Sub New()
        dict = New System.Collections.Generic.Dictionary(Of String, String)
    End Sub
    Protected Sub New(info As SerializationInfo, _
          context As StreamingContext)
        dict = New System.Collections.Generic.Dictionary(Of String, String)
        For Each entry As SerializationEntry In info
            dict.Add(entry.Name, DirectCast(entry.Value, String))
        Next
    End Sub
    Public Sub GetObjectData(info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData
        For Each key As String in dict.Keys
            info.AddValue(key, dict.Item(key))
        Next
    End Sub
End Class

C#에서도 동일:

public class StringStringDictionary : ISerializable
{
    public System.Collections.Generic.Dictionary<string, string> dict;
    public StringStringDictionary()
    {
        dict = new System.Collections.Generic.Dictionary<string, string>();
    }
    protected StringStringDictionary(SerializationInfo info, StreamingContext context)
    {
        dict = new System.Collections.Generic.Dictionary<string, string>();
        foreach (SerializationEntry entry in info)
            dict.Add(entry.Name, (string)entry.Value);
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        foreach (string key in dict.Keys)
            info.AddValue(key, dict[key]);
    }
}

호출 대상:

string MyJsonString = "{ \"key1\": \"value1\", \"key2\": \"value2\"}";
System.Runtime.Serialization.Json.DataContractJsonSerializer dcjs = new
  System.Runtime.Serialization.Json.DataContractJsonSerializer(
    typeof(StringStringDictionary));
System.IO.MemoryStream ms = new
  System.IO.MemoryStream(Encoding.UTF8.GetBytes(MyJsonString));
StringStringDictionary myfields = (StringStringDictionary)dcjs.ReadObject(ms);
Response.Write("Value of key2: " + myfields.dict["key2"]);

C#과 VB가 혼재되어 죄송합니다.네트워크...

다른 답변에 JSON의 null 값 체크를 추가했습니다.

저도 같은 문제가 있어서 제가 직접 쓴 거예요.이 솔루션은, 복수의 레벨로 역직렬화할 수 있기 때문에, 다른 회답과는 다릅니다.

json 문자열을 전송하여 역직렬화하십시오.ToDictionary 함수는 강하게 입력되지 않은 객체를 반환합니다.

private Dictionary<string, object> deserializeToDictionary(string jo)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
    var values2 = new Dictionary<string, object>();
    foreach (KeyValuePair<string, object> d in values)
    {
        if (d.Value != null && d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
        {
            values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
        }
        else
        {
            values2.Add(d.Key, d.Value);
        }
    }
    return values2;
}

예: 반환됩니다.Dictionary<string, object>Facebook JSON ★★★★★★★★★★★★★★★★★★」

private void button1_Click(object sender, EventArgs e)
{
    string responsestring = "{\"id\":\"721055828\",\"name\":\"Dasun Sameera
        Weerasinghe\",\"first_name\":\"Dasun\",\"middle_name\":\"Sameera\",\"last_name\":\"Weerasinghe\",\"username\":\"dasun\",\"gender\":\"male\",\"locale\":\"en_US\",
        hometown: {id: \"108388329191258\", name: \"Moratuwa, Sri Lanka\",}}";
    Dictionary<string, object> values = deserializeToDictionary(responsestring);
}

은 주 a로 더: 페 further 、 note note 、 note note note note note 。Dictionary<string, object>★★★★★★ 。

의 어딘가에서 및 를 사용하고 있는 으로 합니다.System.Runtime.Serialization.Json데이터 계약, 데이터 계약

gis.stackexchange.com의 답변에는 다음과 같은 흥미로운 링크가 있습니다.archive.org을 사용하여 복구해야 했습니다만, 이 솔루션은 거의 완벽한 솔루션을 제공합니다.커스텀 솔루션IDataContractSurrogate이치노나는 그것을 쉽게 확장할 수 있었다.

그래도 내가 많이 바꿨어원본 소스를 사용할 수 없게 되었으므로 여기에 전체 클래스를 게시합니다.

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;

namespace JsonTools
{
    /// <summary>
    /// Allows using Dictionary&lt;String,String&gt; and Dictionary&lt;String,Boolean&gt; types, and any others you'd like to add.
    /// Source: https://web.archive.org/web/20100317222656/my6solutions.com/post/2009/06/30/DataContractSerializer-DataContractJsonSerializer-JavaScriptSerializer-XmlSerializer-for-serialization.aspx
    /// </summary>
    public class JsonSurrogate : IDataContractSurrogate
    {
        /// <summary>
        /// Deserialize an object with added support for the types defined in this class.
        /// </summary>
        /// <typeparam name="T">Contract class</typeparam>
        /// <param name="json">JSON String</param>
        /// <param name="encoding">Text encoding</param>
        /// <returns>The deserialized object of type T</returns>
        public static T Deserialize<T>(String json, Encoding encoding)
        {
            if (encoding == null)
                encoding = new UTF8Encoding(false);
            DataContractJsonSerializer deserializer = new DataContractJsonSerializer(
                typeof(T), new Type[0], int.MaxValue, true, new JsonSurrogate(), false);
            using (MemoryStream stream = new MemoryStream(encoding.GetBytes(json)))
            {
                T result = (T)deserializer.ReadObject(stream);
                return result;
            }
        }

        // make sure all values in this are classes implementing JsonSurrogateObject.
        private static Dictionary<Type, Type> KnownTypes = 
            new Dictionary<Type, Type>()
            {
                {typeof(Dictionary<String, String>), typeof(SSDictionary)},
                {typeof(Dictionary<String, Boolean>), typeof(SBDictionary)}
            };

        #region Implemented surrogate dictionary classes

        [Serializable]
        public class SSDictionary : SurrogateDictionary<String>
        {
            public SSDictionary() : base() {}
            protected SSDictionary (SerializationInfo info, StreamingContext context) : base(info, context) {}
        }
        [Serializable]
        public class SBDictionary : SurrogateDictionary<Boolean>
        {
            public SBDictionary() : base() {}
            protected SBDictionary (SerializationInfo info, StreamingContext context) : base(info, context) {}
        }

        #endregion

        /// <summary>Small interface to easily extract the final value from the object.</summary>
        public interface JsonSurrogateObject
        {
            Object DeserializedObject { get; }
        }

        /// <summary>
        /// Class for deserializing any simple dictionary types with a string as key.
        /// </summary>
        /// <typeparam name="T">Any simple type that will be deserialized correctly.</typeparam>
            [Serializable]
        public abstract class SurrogateDictionary<T> : ISerializable, JsonSurrogateObject
        {
            public Object DeserializedObject { get { return dict; } }
            private Dictionary<String, T> dict;

            public SurrogateDictionary()
            {
                dict = new Dictionary<String, T>();
            }

            // deserialize
            protected SurrogateDictionary(SerializationInfo info, StreamingContext context)
            {
                dict = new Dictionary<String, T>();
                foreach (SerializationEntry entry in info)
                {
                    // This cast will only work for base types, of course.
                    dict.Add(entry.Name, (T)entry.Value);
                }
            }
            // serialize
            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                foreach (String key in dict.Keys)
                {
                    info.AddValue(key, dict[key]);
                }
            }

        }

        /// <summary>
            /// Uses the KnownTypes dictionary to get the surrogate classes.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Type GetDataContractType(Type type)
        {
            Type returnType;
            if (KnownTypes.TryGetValue(type, out returnType))
            {
                return returnType;
            }
            return type;
        }

        public object GetObjectToSerialize(object obj, Type targetType)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        ///     Gets the object out of the surrogate datacontract object. This function is the reason all surrogate objects need to implement the JsonSurrogateObject class.
        /// </summary>
        /// <param name="obj">Result of the deserialization</param>
        /// <param name="targetType">Expected target type of the deserialization</param>
        /// <returns></returns>
        public object GetDeserializedObject(object obj, Type targetType)
        {
            if (obj is JsonSurrogateObject)
            {
                return ((JsonSurrogateObject)obj).DeserializedObject;
            }
            return obj;
        }

        public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
        {
            return null;
        }

        #region not implemented

        public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
        {
            throw new NotImplementedException();
        }

        public object GetCustomDataToExport(Type clrType, Type dataContractType)
        {
            throw new NotImplementedException();
        }

        public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
        {
            throw new NotImplementedException();
        }

        public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

를 참조).SurrogateDictionary가 상속되는 을 확인합니다.JsonSurrogateObject해 주세요.KnownTypes포함모든 SubgaryDictionary의 기초가 될 수 .Dictionary<String,T>여기서 T는 올바르게 역직렬화 되는 타입입니다.

전화는 매우 간단합니다.

MyObjtype newObj = JsonSurrogate.Deserialize<MyObjtype>(jsonStr, encoding);

공백이 포함된 키 문자열을 사용하는 데 문제가 있다는 점에 유의하십시오.키 문자열은 최종 목록에 없습니다.단순히 json 사양에 어긋난 것일 수도 있고, 제가 호출한 API가 제대로 구현되지 않은 것일 수도 있습니다. 잘 모르겠습니다.어쨌든, 나는 이것을 raw json 데이터에 밑줄로 치환하고, 역직렬화 후에 사전을 수정하는 것으로 해결했다.

위의 코멘트에 근거해, 시험해 주세요.JsonConvert.DeserializeObject<Dictionary<string,dynamic>>(json)

var json = @"{""key1"":1,""key2"":""value2"", ""object1"":{""property1"":""value1"",""property2"":[2,3,4,5,6,7]}}";
var parsedObject = JsonConvert.DeserializeObject<Dictionary<string,dynamic>>(json);

복잡한 오브젝트나 리스트에도 효과가 있는 것 같습니다.

내 접근 방식은 JObject 또는 ExpandObject를 사용하지 않고 IDirectionary로 직접 역직렬화됩니다.이 코드는 기본적으로 JSON에 있는 ExpandoObjectConverter 클래스에서 복사된 변환기를 사용합니다.NET 소스 코드. 단 ExpandoObject 대신 IDictionary를 사용합니다.

사용방법:

var settings = new JsonSerializerSettings()
{
    Converters = { new DictionaryConverter() },
};
var result = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, settings);

코드:

// based on ExpandoObjectConverter, but using arrays instead of IList, to behave similar to System.Web.Script.Serialization.JavaScriptSerializer
public class DictionaryConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return ReadValue(reader);
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IDictionary<string, object>));
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    private object ReadValue(JsonReader reader)
    {
        while (reader.TokenType == JsonToken.Comment)
        {
            if (!reader.Read())
                throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");
        }

        switch (reader.TokenType)
        {
            case JsonToken.StartObject:
                return ReadObject(reader);
            case JsonToken.StartArray:
                return ReadList(reader);
            default:
                if (IsPrimitiveToken(reader.TokenType))
                    return reader.Value;

                throw JsonSerializationExceptionCreate(reader, string.Format(CultureInfo.InvariantCulture, "Unexpected token when converting IDictionary<string, object>: {0}", reader.TokenType));
        }
    }

    private object ReadList(JsonReader reader)
    {
        List<object> list = new List<object>();

        while (reader.Read())
        {
            switch (reader.TokenType)
            {
                case JsonToken.Comment:
                    break;
                default:
                    object v = ReadValue(reader);

                    list.Add(v);
                    break;
                case JsonToken.EndArray:
                    return list;
            }
        }

        throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");
    }

    private object ReadObject(JsonReader reader)
    {
        IDictionary<string, object> dictionary = new Dictionary<string, object>();
        while (reader.Read())
        {
            switch (reader.TokenType)
            {
                case JsonToken.PropertyName:
                    string propertyName = reader.Value.ToString();

                    if (!reader.Read())
                        throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");

                    object v = ReadValue(reader);

                    dictionary[propertyName] = v;
                    break;
                case JsonToken.Comment:
                    break;
                case JsonToken.EndObject:
                    return dictionary;
            }
        }

        throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");
    }

    //based on internal Newtonsoft.Json.JsonReader.IsPrimitiveToken
    internal static bool IsPrimitiveToken(JsonToken token)
    {
        switch (token)
        {
            case JsonToken.Integer:
            case JsonToken.Float:
            case JsonToken.String:
            case JsonToken.Boolean:
            case JsonToken.Undefined:
            case JsonToken.Null:
            case JsonToken.Date:
            case JsonToken.Bytes:
                return true;
            default:
                return false;
        }
    }

    // based on internal Newtonsoft.Json.JsonSerializationException.Create
    private static JsonSerializationException JsonSerializationExceptionCreate(JsonReader reader, string message, Exception ex = null)
    {
        return JsonSerializationExceptionCreate(reader as IJsonLineInfo, reader.Path, message, ex);
    }

    // based on internal Newtonsoft.Json.JsonSerializationException.Create
    private static JsonSerializationException JsonSerializationExceptionCreate(IJsonLineInfo lineInfo, string path, string message, Exception ex)
    {
        message = JsonPositionFormatMessage(lineInfo, path, message);

        return new JsonSerializationException(message, ex);
    }

    // based on internal Newtonsoft.Json.JsonPosition.FormatMessage
    internal static string JsonPositionFormatMessage(IJsonLineInfo lineInfo, string path, string message)
    {
        if (!message.EndsWith(Environment.NewLine))
        {
            message = message.Trim();

            if (!message.EndsWith(".", StringComparison.Ordinal))
                message += ".";

            message += " ";
        }

        message += string.Format(CultureInfo.InvariantCulture, "Path '{0}'", path);

        if (lineInfo != null && lineInfo.HasLineInfo())
            message += string.Format(CultureInfo.InvariantCulture, ", line {0}, position {1}", lineInfo.LineNumber, lineInfo.LinePosition);

        message += ".";

        return message;
    }
}

번거롭지만 기본 모델 바인더를 사용하려면 POST 형식과 같은 숫자 색인 값을 사용해야 할 것 같습니다.

이 문서의 다음 발췌를 참조하십시오.http://msdn.microsoft.com/en-us/magazine/hh781022.aspx

JSON 요청은 다소 직관에 어긋나지만 동일한 요구 사항을 가지고 있습니다. 즉, 이름 지정 후 구문 형식을 준수해야 합니다.예를 들어 이전 UnitPrice 컬렉션의 JSON payload를 예로 들어 보겠습니다.이 데이터의 순수 JSON 배열 구문은 다음과 같이 표시됩니다.

[ 
  { "Code": "USD", "Amount": 100.00 },
  { "Code": "EUR", "Amount": 73.64 }
]

그러나 기본값 공급자와 모델 바인더는 데이터를 JSON 양식 게시물로 나타내야 합니다.

{
  "UnitPrice[0].Code": "USD",
  "UnitPrice[0].Amount": 100.00,

  "UnitPrice[1].Code": "EUR",
  "UnitPrice[1].Amount": 73.64
}

복잡한 오브젝트 수집 시나리오는 구문이 모든 개발자에게 명확하다고는 할 수 없기 때문에 개발자가 직면하는 가장 일반적인 문제 시나리오 중 하나입니다.그러나 복잡한 컬렉션을 게시하기 위한 비교적 간단한 구문을 익히면 이러한 시나리오를 훨씬 쉽게 처리할 수 있습니다.

방금 Rest Sharp에 구현했습니다. 글은 나에게 도움이 되었다.

링크에 있는 코드 외에 여기에 내 코드가 있습니다. 해서 '이렇게 하다'가요.Dictionary결과를 얻을 수 있습니다.

var jsonClient = new RestClient(url.Host);
jsonClient.AddHandler("application/json", new DynamicJsonDeserializer());
var jsonRequest = new RestRequest(url.Query, Method.GET);
Dictionary<string, dynamic> response = jsonClient.Execute<JObject>(jsonRequest).Data.ToObject<Dictionary<string, dynamic>>();

예상되는 JSON의 종류에 유의하십시오.저 같은 경우에는 여러 속성을 가진 단일 개체를 검색하고 있었습니다.첨부된 링크에서 작성자는 목록을 검색하고 있었습니다.

게임에 조금 늦었지만, 위의 해결책들 중 어느 것도 나를 순수하고 단순한 방향으로 인도하지 않았다.NET, json.net 솔루션 없음여기 있습니다. 결국 매우 단순해졌습니다.다음은 표준에서의 동작 방법의 완전한 예를 제시하겠습니다.NET Json 직렬화 예제에서는 루트 개체와 하위 개체 모두에 사전이 있습니다.

여기서 중요한 것은 설정을 시리얼라이저의 두 번째 파라미터로 해석하는 것입니다.

DataContractJsonSerializerSettings settings =
                       new DataContractJsonSerializerSettings();
                    settings.UseSimpleDictionaryFormat = true;

아래 전체 코드:

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

    namespace Kipon.dk
    {
        public class JsonTest
        {
            public const string EXAMPLE = @"{
                ""id"": ""some id"",
                ""children"": {
                ""f1"": {
                    ""name"": ""name 1"",
                    ""subs"": {
                    ""1"": { ""name"": ""first sub"" },
                    ""2"": { ""name"": ""second sub"" }
                    }
                },
                ""f2"": {
                    ""name"": ""name 2"",
                    ""subs"": {
                    ""37"": { ""name"":  ""is 37 in key""}
                    }
                }
                }
            }
            ";

            [DataContract]
            public class Root
            {
                [DataMember(Name ="id")]
                public string Id { get; set; }

                [DataMember(Name = "children")]
                public Dictionary<string,Child> Children { get; set; }
            }

            [DataContract]
            public class Child
            {
                [DataMember(Name = "name")]
                public string Name { get; set; }

                [DataMember(Name = "subs")]
                public Dictionary<int, Sub> Subs { get; set; }
            }

            [DataContract]
            public class Sub
            {
                [DataMember(Name = "name")]
                public string Name { get; set; }
            }

            public static void Test()
            {
                var array = System.Text.Encoding.UTF8.GetBytes(EXAMPLE);
                using (var mem = new System.IO.MemoryStream(array))
                {
                    mem.Seek(0, System.IO.SeekOrigin.Begin);
                    DataContractJsonSerializerSettings settings =
                       new DataContractJsonSerializerSettings();
                    settings.UseSimpleDictionaryFormat = true;

                    var ser = new DataContractJsonSerializer(typeof(Root), settings);
                    var data = (Root)ser.ReadObject(mem);
                    Console.WriteLine(data.Id);
                    foreach (var childKey in data.Children.Keys)
                    {
                        var child = data.Children[childKey];
                        Console.WriteLine(" Child: " + childKey + " " + child.Name);
                        foreach (var subKey in child.Subs.Keys)
                        {
                            var sub = child.Subs[subKey];
                            Console.WriteLine("   Sub: " + subKey + " " + sub.Name);
                        }
                    }
                }
            }
        }
    }

Tiny-JSON을 사용할 수 있습니다.

string json = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
IDictionary<string, string> dict = Tiny.Json.Decode<Dictionary<string, string>>(json);

는 '쓰다'를 사용하는 것이 .System.Runtime.Serialization.Json의 입니다.NET 4.5

[DataContract]
public class Foo
{
   [DataMember(Name = "data")]
   public Dictionary<string,string> Data { get; set; }
}

그런 다음 다음과 같이 사용합니다.

var serializer = new DataContractJsonSerializer(typeof(List<Foo>));
var jsonParams = @"{""data"": [{""Key"":""foo"",""Value"":""bar""}] }";
var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonParams));

var obj = serializer.ReadObject(stream);
Console.WriteLine(obj);

다음은 시스템과의 솔루션입니다.텍스트, Json.나중에 필요한 유형으로 변환할 수 있는 중첩된 개체에 대한 json 문자열을 얻을 수 있습니다.

public static Dictionary<string,string> JsonToDictionary(this string json)
        {
            var objectValues = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
            var stringValues = objectValues.Select(o => new KeyValuePair<string, string>(o.Key, o.Value?.ToString()));
            return stringValues.ToDictionary(pair => pair.Key, pair => pair.Value);
        }

다음은 중첩된 개체에서 값을 가져오는 사용 예입니다.

 var result= json.JsonToDictionary()["outerField"]
                .JsonToDictionary()["innerField"];

이 솔루션에서는 [12, 13]과 같은 배열로 시작하는 json 개체는 다루지 않습니다.이러한 오브젝트는 선두에서 배열로 읽혀질 수 있으며, 각 아이템에 확장 방법을 적용할 수 있습니다.이러한 오브젝트는 아이템이 자신의 속성을 가진 복잡한 오브젝트인 경우입니다.

언급URL : https://stackoverflow.com/questions/1207731/how-can-i-deserialize-json-to-a-simple-dictionarystring-string-in-asp-net

반응형