ดูเหมือนว่าคำตอบทั้งหมดเหล่านี้ที่นี่เพียงแค่สมมติว่าคุณสามารถดึงสายเล็ก ๆ ออกมาจากวัตถุที่ใหญ่กว่า ... สำหรับผู้ที่ต้องการกำจัดวัตถุขนาดใหญ่ด้วยพจนานุกรมเช่นนี้ในที่ใดที่หนึ่งในแผนที่และผู้ที่ใช้ System.Runtime.Serialization.Json
ระบบ DataContract นี่คือ ทางออก:
คำตอบใน 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<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
}
}
ในการเพิ่มประเภทที่รองรับใหม่ให้กับคลาสคุณเพียงแค่เพิ่มคลาสของคุณให้โครงสร้างและฟังก์ชั่นที่ถูกต้อง (ดูSurrogateDictionary
ตัวอย่าง) ตรวจสอบให้แน่ใจว่าสืบทอดJsonSurrogateObject
และเพิ่มการแม็พประเภทลงในKnownTypes
พจนานุกรม SurrogateDictionary ที่รวมอยู่สามารถใช้เป็นพื้นฐานสำหรับการใด ๆDictionary<String,T>
ประเภทที่ T เป็นประเภทใด ๆ ที่ไม่ทำการทำการ deserialize อย่างถูกต้อง
เรียกง่าย ๆ ว่า:
MyObjtype newObj = JsonSurrogate.Deserialize<MyObjtype>(jsonStr, encoding);
โปรดทราบว่าด้วยเหตุผลบางอย่างสิ่งนี้มีปัญหาในการใช้สตริงคีย์ซึ่งมีช่องว่าง พวกเขาไม่ได้อยู่ในรายการสุดท้าย อาจเป็นไปได้ว่ามันเป็นเพียงแค่รายละเอียดของ json และ api ที่ฉันโทรหานั้นถูกนำไปใช้งานไม่ดี ไม่รู้สินะ. อย่างไรก็ตามฉันแก้ไขได้โดยการแทนที่ regex ด้วยการขีดเส้นใต้ในข้อมูล json ดิบและแก้ไขพจนานุกรมหลังจากการดีซีเรียลไลเซชัน
JavaScriptSerizlizer
ใช้ใน ASP.NET MVC และไม่เลิกใช้แล้ว