यहाँ समस्या समाधान के बारे में मेरे विचार कर रहे हैं। नेट का कस्टम deserialization एपीआई पारदर्शी नहीं है, यानी मेरी कक्षा पदानुक्रम को प्रभावित करता है।
असल में यह कोई समस्या नहीं है जब आपके प्रोजेक्ट में 10-20 कक्षाएं हों, हालांकि यदि आपके पास हजारों कक्षाओं के साथ बड़ी परियोजना है, तो आप इस तथ्य के बारे में विशेष रूप से खुश नहीं हैं कि आपको जेसन के साथ अपने ओओपी डिज़ाइन का पालन करने की आवश्यकता है नेट आवश्यकताओं।
जेसन.Net पीओसीओ ऑब्जेक्ट्स के साथ अच्छा है जो बनाए जाने के बाद आबादी (प्रारंभिक) हैं। लेकिन यह सभी मामलों में सच नहीं है, कभी-कभी आप अपने ऑब्जेक्ट्स को कन्स्ट्रक्टर के अंदर शुरू करते हैं। और उस प्रारंभिकरण को करने के लिए आपको 'सही' तर्क पारित करने की आवश्यकता है।ये 'सही' तर्क या तो धारावाहिक पाठ के अंदर हो सकते हैं या वे पहले से ही बनाया जा सकता है और कुछ समय पहले शुरू किया जा सकता है। दुर्भाग्य से जेसन.Net deserialization के दौरान डिफ़ॉल्ट मानों को उन तर्कों से गुजरता है जिन्हें वह समझ में नहीं आता है, और मेरे मामले में यह हमेशा ArgumentNullException का कारण बनता है।
समाधान:
यहाँ है दृष्टिकोण है कि तर्क या तो धारावाहिक या गैर धारावाहिक के किसी सेट का उपयोग कर अक्रमांकन दौरान वास्तविक कस्टम वस्तु निर्माण की अनुमति देता है, मुख्य समस्या यह है कि दृष्टिकोण उप इष्टतम, इसके बारे में 2 चरणों की आवश्यकता है वस्तु प्रति अक्रमांकन कस्टम अक्रमांकन की आवश्यकता है कि है, लेकिन यह काम करता है और deserializing जिस तरह से आप इसकी आवश्यकता की वस्तुओं की अनुमति देता है, इसलिए यहाँ जाता है:
public class FactoryConverter<T> : Newtonsoft.Json.JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
T value = CreateAndPopulate(objectType, serializer.Deserialize<Dictionary<String, String>>(reader));
if (value == null)
throw new JsonSerializationException("No object created.");
return value;
}
/// <summary>
/// Creates an object which will then be populated by the serializer.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns></returns>
public abstract T CreateAndPopulate(Type objectType, Dictionary<String, String> jsonFields);
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
/// </summary>
/// <value>
/// <c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
/// </value>
public override bool CanWrite
{
get
{
return false;
}
}
}
:
पहले हम CustomCreationConverter वर्ग निम्नलिखित तरीके से पुनः
public class FooFactory : FactoryConverter<Foo>
{
public FooFactory(Bar bar)
{
this.Bar = bar;
}
public Bar Bar { get; private set; }
public override Foo Create(Type objectType, Dictionary<string, string> arguments)
{
return new Foo(Bar, arguments["X"], arguments["Y"]);
}
}
यहाँ नमूना कोड है:
var bar = new Bar("BarObject");
var fooSrc = new Foo
(
bar,
"A", "B"
);
var str = JsonConvert.SerializeObject(fooSrc);
var foo = JsonConvert.DeserializeObject<Foo>(str, new FooFactory(bar));
Console.WriteLine(str);
इस मामले foo में एक तर्क है कि हम के दौरान एक फू निर्माता को पारित करने के लिए आवश्यक होता है 363,210
अगला हम कारखाने वर्ग है कि हमारे फू पैदा करेगा बनाने अक्रमांकन।
कोई विचार नहीं क्यों serializer लेखकों को यह कम प्राथमिकता मानते हैं। मैंने हमेशा कम-स्तरीय हैक के बिना अपरिवर्तनीय ऑब्जेक्ट्स बनाने में सक्षम होने पर विचार किया है, वास्तव में एक बुनियादी इंटरफेस आधारित सीरिएलाइज़र के पास मूलभूत सुविधाओं में से एक है। – CodesInChaos
@CodeInChaos क्यों के लिए के रूप में Protobuf शुद्ध * कम से कम एक अन्य (किराए की रूपांतरण) का समर्थन करता है सूचीबद्ध सभी 4 विकल्प, * और ... बस 'कह –
@CodeInChaos: बस, जो वास्तव में बहुत कठिन है –