5

सादगी के उद्देश्यों के लिए, मैं फल का उपयोग करके अपना नमूना कोड दिखाऊंगा। वास्तविकता में मैं कुछ और सार्थक कर रहा हूं (हमें उम्मीद है)।अमान्य enum आइटम deserializing अपवाद से कैसे बचें?

public enum FruitType 
{ 
    Apple, 
    Orange, 
    Banana 
} 

और एक वर्ग:

[Serializable] 
public class Fruit 
{ 
    public FruitType FruitType { get; set; } 
    public Fruit(FruitType type) 
    { 
     this.FruitType = type; 
    } 
} 

हम क्रमानुसार सकता है और यह डी-क्रमानुसार कहते हैं कि हम एक enum करते हैं। अब, की सुविधा देता है enum संशोधित करते हैं, इतना है कि यह अब है:

public enum FruitType 
{ 
    GreenApple, 
    RedApple, 
    Orange, 
    Banana 
} 

जब डी-serializing पहले धारावाहिक वस्तुओं, आप Apple (मूल enum आइटम) के रूप में एक System.InvalidOperation अपवाद मान्य नहीं है। वस्तु को डी-धारावाहिक नहीं मिलता है।

[XmlElement(ElementName = "Mode")] 
    public FruitType FruitType { get; set; } 

अब, de-क्रमबद्धता के दौरान वर्ष संपत्ति नजरअंदाज कर दिया जाता:

एक तरह से मैं इस को हल करने में सक्षम था जब यह धारावाहिक हो जाता है एक अलग नाम Fruit कक्षा में FruitType संपत्ति देने के लिए इस प्रकार था जैसा कि यह नहीं मिला है। मैं जानना चाहता हूं कि डी-सीरियलाइजेशन के दौरान अमान्य एनम आइटम को अनदेखा/छोड़ने का कोई तरीका है, ताकि कोई अपवाद फेंक दिया न जाए और ऑब्जेक्ट को अभी भी डी-सीरियलाइज किया जा सके।

+1

जुड़ा हुआ सवाल जहां मैं एक काम कर नमूना परियोजना शामिल करने के लिए मेरा उत्तर देखें चाहते हैं कि मिलना चाहिए: http://stackoverflow.com/a/10709040 – user423430

उत्तर

3

Apple छोड़ें और इसे ObsoleteAttribute के साथ चिह्नित करें। इस तरह, Apple का उपयोग कर कोई भी कोड एक कंपाइलर चेतावनी उत्पन्न करेगा।

+0

मैंने 'अप्रचलित]' ऐप्पल 'enum आइटम से ऊपर जोड़ा। लेकिन, मुझे अभी भी निम्न अपवाद मिलता है जब deserializing और पुरानी वस्तु: इंस्टेंस सत्यापन त्रुटि: 'Apple' FruitType के लिए मान्य मान नहीं है। – Elan

0

मैंने similar question पोस्ट किया है और जब deserializer XML फ़ाइल में ऐप्पल से मुकाबला करता है तो अपवाद को पकड़ने के लिए एक आसान तरीका नहीं मिला है। मैं अनुपलब्ध गुणों या तत्वों के लिए deserialiation के दौरान अन्य अपवादों का एक समूह पकड़ सकता है, लेकिन एक अवैध enum मूल्य के लिए नहीं। अमान्य enum मान (आपके मामले में ऐप्पल) मुझे deserialization से बाहर उड़ाता है।

एक संभावित समाधान फल वर्ग पर IXMLSerializable को लागू करना है। जब IXMLSerailizable.ReadXML() विधि deserializer द्वारा बुलाया जाता है, तो आपको यह देखना होगा कि आपको क्या पारित किया जा रहा है। जब मूल्य "ऐप्पल" कुछ तर्क के आधार पर ग्रीनएपल या रेडएपल को enum सेट करता है।

0

मैं अपने आप को इसी तरह के उत्तरों की तलाश कर रहा हूं, और अपवाद को पकड़ने के लिए यह लिखा है जब XML में एक enum के लिए मान है जो वैध नहीं है। यह उस तत्व को हटा देता है, और फिर से deserialize करने की कोशिश करता है। यदि तत्व आवश्यक है, तो भी आपको अपवाद मिलेगा। यह अपूर्ण है, लेकिन आप जिस तरह से ज्यादातर जहां होने के लिए

private const string XmlError = "There is an error in XML document "; 
    private const string InstanceValidationError = "Instance validation error:"; 
    private static readonly Regex XmlErrorRegex = new Regex("There is an error in XML document \\((\\d+), (\\d+)\\)."); 
    private static readonly Regex InstanceValidationErrorRegex = new Regex("Instance validation error: '(\\S+)' is not a valid value for (\\S+)."); 
    private const string TagFinderString = "\\>{0}\\</(\\S+)\\>"; 

    /// <summary> 
    /// Helper method to deserialize xml message 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="message"></param> 
    /// <returns></returns> 
    public T Deserialize(string message) 
    { 
     var result = default(T); 
     if (!string.IsNullOrEmpty(message)) 
     { 
      using (var reader = new StringReader(message)) 
      { 
       try 
       { 
        result = (T)_serializer.Deserialize(reader); 
       } 
       catch (InvalidOperationException ex) 
       { 
        if (ex.Message.StartsWith(XmlError)) 
        { 
         if(ex.InnerException != null && ex.InnerException.Message.StartsWith(InstanceValidationError)) 
         { 
          var instanceValidationErrorMatches = InstanceValidationErrorRegex.Matches(ex.InnerException.Message); 
          if (instanceValidationErrorMatches.Count > 0) 
          { 
           var locationMatches = XmlErrorRegex.Matches(ex.Message); 
           var startIndex = GetStartIndex(message, locationMatches); 
           var match = instanceValidationErrorMatches[0]; 
           if(match.Groups.Count > 0) 
           { 
            var toRemove = GetToRemove(message, match, startIndex); 

            return Deserialize(message.Replace(toRemove, string.Empty)); 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
     return result; 
    } 

    private static string GetToRemove(string message, Match match, int startIndex) 
    { 
     var value = match.Groups[1]; 
     var tagFinder = new Regex(string.Format(TagFinderString, value)); 
     var tagFinderMatches = tagFinder.Matches(message.Substring(startIndex)); 
     var tag = tagFinderMatches[0].Groups[1]; 

     return string.Format("<{0}>{1}</{0}>", tag, value); 
    } 

    private static int GetStartIndex(string message, MatchCollection locationMatches) 
    { 
     var startIndex = 0; 
     if (locationMatches.Count > 0) 
     { 
      var lineNumber = int.Parse(locationMatches[0].Groups[1].Value); 
      var charIndex = int.Parse(locationMatches[0].Groups[2].Value); 
      using (var locationFinder = new StringReader(message)) 
      { 
       for (var i = 1; i < lineNumber; i++) 
       { 
        startIndex += locationFinder.ReadLine().Length; 
       } 
      } 
      startIndex += charIndex; 
     } 
     return startIndex; 
    } 
संबंधित मुद्दे