Question35697018 xml IsNullable

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Runtime.Serialization;
using System.ComponentModel;


    public interface IClassName
    {
        string Child1 { get; set; }

        string Child2 { get; set; }
    }

    namespace V1
    {
        [XmlRoot("ClassName")]
        //[DataContract]
        public class ClassName : IClassName
        {
            //[DataMember]
            [XmlElement("Child1")]
            public string Child1 { get; set; }

            //[DataMember]
            [XmlElement("Child2", IsNullable = true)]
            public string Child2 { get; set; }
        }
    }

    namespace V2
    {
        public struct CustomXmlNilTextWrapper
        {
            bool forceNull;
            string value;

            public static implicit operator CustomXmlNilTextWrapper(string value)
            {
                return new CustomXmlNilTextWrapper(value);
            }

            public static implicit operator string(CustomXmlNilTextWrapper wrapper)
            {
                return wrapper.Value;
            }

            public CustomXmlNilTextWrapper(string value)
            {
                this.value = value;
                this.forceNull = value == null;
            }

            [XmlAttribute("nil")]
            public bool ForceNull { get { return forceNull; } set { forceNull = value; } }

            public bool ShouldSerializeForceNull() { return ForceNull == true; }

            [XmlText]
            public string Value { get { return ForceNull ? null : value ?? string.Empty; } set { this.value = value; } }
        }

        [XmlRoot("ClassName")]
        //[DataContract]
        public class ClassName : IClassName
        {
            //[DataMember]
            [XmlElement("Child1")]
            public string Child1 { get; set; }

            //[DataMember]
            [XmlIgnore]
            public string Child2 { get; set; }

            [XmlElement("Child2")]
            [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
            //[IgnoreDataMember]
            public CustomXmlNilTextWrapper Child2Xml { get { return Child2; } set { Child2 = value; } }
        }
    }

    public static class XmlSerializationHelper
    {
        public static T LoadFromXML<T>(this string xmlString)
        {
            using (StringReader reader = new StringReader(xmlString))
            {
                return (T)new XmlSerializer(typeof(T)).Deserialize(reader);
            }
        }

        public static string GetXml<T>(this T obj)
        {
            using (var textWriter = new StringWriter())
            {
                var settings = new XmlWriterSettings() { Indent = true, IndentChars = "    " }; // For cosmetic purposes.
                var ns = new XmlSerializerNamespaces();
                ns.Add("", ""); // Suppress default namespaces.
                using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                    new XmlSerializer(obj.GetType()).Serialize(xmlWriter, obj, ns);
                return textWriter.ToString();
            }
        }
    }

    public static class ConsoleAndDebug
    {
        public static void WriteLine(object s)
        {
            Console.WriteLine(s);
            Debug.WriteLine(s);
        }
    }

    public class TestClass
    {
        public static void Test()
        {
			ConsoleAndDebug.WriteLine("XML serialization test for custom nil attribute:");
            Test<V2.ClassName>();
			ConsoleAndDebug.WriteLine("XML serialization test for standard nil attribute:");
            Test<V1.ClassName>();
        }

        public static void Test<ClassName>() where ClassName : IClassName, new()
        {
            ConsoleAndDebug.WriteLine(string.Format("XML output for \"{0}\":\n", typeof(ClassName).FullName));
            var strings = new[] { null, string.Empty, "FooBar" };

            for (int iChild1 = 0; iChild1 < strings.Length; iChild1++)
            {
                for (int iChild2 = 0; iChild2 < strings.Length; iChild2++)
                {
                    var test = new ClassName() { Child1 = strings[iChild1], Child2 = strings[iChild2] };
                    var xml = test.GetXml();
                    var testS1 = strings[iChild1] != null ? '"' + strings[iChild1] + '"' : "null";
                    var testS2 = strings[iChild2] != null ? '"' + strings[iChild2] + '"' : "null";
                    ConsoleAndDebug.WriteLine(string.Format("Output for Child1 = {0} and Child2 = {1}", testS1, testS2));
                    ConsoleAndDebug.WriteLine(xml);
                    ConsoleAndDebug.WriteLine("");

                    var test2 = xml.LoadFromXML<ClassName>();
                    if (test2.Child2 != test.Child2)
                    {
                        throw new InvalidOperationException("Child2 value not deserialized correctly");
                    }
                }
            }

            ConsoleAndDebug.WriteLine("");
        }
    }
						
	public class Program
	{
		public static void Main()
		{
			TestClass.Test();
		}
	}
;