Es scheint, dass all diese Antworten hier davon ausgehen, dass Sie diese kleine Zeichenkette aus einem größeren Objekt herausholen können... für Leute, die einfach ein großes Objekt mit einem solchen Wörterbuch irgendwo innerhalb der Abbildung deserealisieren wollen und die die System.Runtime.Serialization.Json
DataContract-System, hier ist eine Lösung:
Eine Antwort auf gis.stackexchange.com hatte dieser interessante Link . Ich musste es mit archive.org wiederherstellen, aber es bietet eine ziemlich perfekte Lösung: eine benutzerdefinierte IDataContractSurrogate
Klasse, in der Sie genau Ihre eigenen Typen implementieren. Ich konnte sie leicht erweitern.
Ich habe allerdings eine Reihe von Änderungen daran vorgenommen. Da die Originalquelle nicht mehr verfügbar ist, werde ich die gesamte Klasse hier veröffentlichen:
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<String,String> and Dictionary<String,Boolean> 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
}
}
Um der Klasse neue unterstützte Typen hinzuzufügen, müssen Sie nur Ihre Klasse hinzufügen und ihr die richtigen Konstruktoren und Funktionen geben (siehe SurrogateDictionary
für ein Beispiel), vergewissern Sie sich, dass es erbt JsonSurrogateObject
und fügen Sie dessen Typzuordnung zur KnownTypes
Wörterbuch. Das mitgelieferte SurrogateDictionary kann als Basis für jedes Dictionary<String,T>
Typen, wobei T ein beliebiger Typ ist, der sich korrekt deserialisieren lässt.
Der Aufruf ist wirklich einfach:
MyObjtype newObj = JsonSurrogate.Deserialize<MyObjtype>(jsonStr, encoding);
Beachten Sie, dass aus irgendeinem Grund dieses Ding hat Probleme mit Schlüssel Zeichenfolgen, die Leerzeichen enthalten; sie waren einfach nicht in der endgültigen Liste vorhanden. Könnte nur sein, es ist einfach gegen json Spezifikationen und die api ich aufgerufen wurde schlecht implementiert, wohlgemerkt; Ich weiß nicht. Wie auch immer, ich löste dies durch Regex-Ersetzung sie mit Unterstrichen in der rohen Json-Daten und Festsetzung des Wörterbuchs nach der Deserialisierung.
1 Stimmen
Zu: Einschränkung 3,
JavaScriptSerizlizer
wird in ASP.NET MVC verwendet und ist nicht mehr veraltet.37 Stimmen
Es ist unglaublich, wie schwierig es war, einen einfachen Weg zu finden, um eine json-Zeichenfolge in etwas zu konvertieren, das ich leicht verwenden konnte, ohne durch viele verschiedene Stackoverflow zu blättern. Es ist so einfach in anderen Sprachen noch Java und C# scheint zu gehen aus dem Weg zu machen das Leben schwer.