0

I'm working on some classes in c#. They need to be serialized to XML to match an existing schema, but I want to build the validation in the code. e.g. something like the below;

public class Address {
        public AddressLineType AddressLine1 {get;set;}
        public AddressLineType AddressLine2 {get;set;}
        public ShortAddressLineType AddressTown {get;set;}
        public ShortAddressLineType AddressCounty {get;set;}
        public PostCodeType PostCode {get;set;}
    }

    public class SimpleString {
        public string Value {get;set;}
        public override string ToString() {
            return Value;
        }
    }

    public class AddressLineType : SimpleString {
        static readonly int maxLength = 60;
        public static explicit operator AddressLineType(string v) {
            if(!(v.Length < maxLength)) throw new Exception("String is to long!");
            AddressLineType s = new AddressLineType();
            s.Value = v;
            return s;
        }
    }

    public class ShortAddressLineType : SimpleString {
        static readonly int maxLength = 30;
        public static explicit operator ShortAddressLineType(string v) {
            if(!(v.Length < maxLength)) throw new Exception("String is to long!");
            ShortAddressLineType s = new ShortAddressLineType();
            s.Value = v;
            return s;
        }
    }

    public class PostCodeType : SimpleString {
        public static explicit operator PostCodeType(string v) {
        Regex regex = new Regex(""); //PostCode pattern..
            if(!(regex.IsMatch(v))) throw new Exception("Regex Validation Failed.");
            PostCodeType s = new PostCodeType();
            s.Value = v;
            return s;
        }
    }

However, when this is serialized the result is;

<CurrentAddress>
 <AddressLine1>
  <Value>3 The Street</Value>
 </AddressLine1>
 <AddressLine2>
  <Value>Foo Town</Value>
 </AddressLine2>
</CurrentAddress>

Is it possible to collapse the special classes so that the result is this instead, but still be able to do validation? e.g. I need to specify that the AddressLineType serialises to it's Value only.

<CurrentAddress>
 <AddressLine1>3 The Street</AddressLine1>
 <AddressLine2>Foo Town</AddressLine2>
</CurrentAddress>

This code prints the result;

Address address = new Address();
address.AddressLine1 = (AddressLineType) "3 The Street";
address.AddressLine2 = (AddressLineType) "Foo Town";

XmlSerializer serializer = new XmlSerializer(typeof(Address));
serializer.Serialize(Console.Out, address);
SB3
  • 19
  • 5
  • 1
    Add `[XmlText]` to `Value`, make `Value` virtual (or have some notification event) and do the validation in the setter. See: [Serialize a C# class to XML with attributes and a single value for the class](https://stackoverflow.com/a/9504236). – dbc Oct 16 '19 at 06:43
  • Does that answer your question, or do you need a more specific answer? Is it important that the exception gets thrown in the explicit operator? – dbc Oct 16 '19 at 16:34
  • That was simpler than I thought and does answer the question. However, how can the string validation be improved? – SB3 Oct 16 '19 at 21:21
  • Not sure I understand your follow-on question. Can't you add a `protected virtual void OnValueChanged()` method and override it in the various subclasses of `SimpleString`? – dbc Oct 16 '19 at 21:27

0 Answers0