1

Enum is automatically deserialized by the WCF service.

[XmlType(Namespace = "http://rca.ws.emitere/2010-11/")]
public enum Animal
{
    [System.Xml.Serialization.XmlEnumAttribute("Cat name")]
    Cat,

    [System.Xml.Serialization.XmlEnumAttribute("Dog name")]
    Dog

}

Using

XmlElement(Form = XmlSchemaForm.Unqualified)]
    public Animal anim{ get; set; }

Can I set the default value, when no match is correct? Right now it generates a serialization error.

I want to return a validation message without changing the wsdl. The web service has several methods and for each of them one should return another message.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38

1 Answers1

0

Unfortunatelly you are trapped in using enum in WCF contract. One option that can work for you is to change type of property anim to String and add other property attributed by XmlIgnore that will contain your desired value after deserialization is completed. Please remember that by this you might have to consider the same "value transfer" for serialization as well.

Let's suppose anim property is contained in:

public class Zoo
{
    [XmlIgnore]
    public Animal? animAsEnum { get; set; }

    public string anim { get; set; }

    [OnDeserialized]
    private void OnDeserializedMethod(StreamingContext context)
    {
        Animal animAsEnum;
        if (Enum.TryParse(anim, out animAsEnum))
        {
            this.animAsEnum = animAsEnum;
        }
    }
}

How it works can be demonstrated as follows:

[TestMethod]
public void Zoo_Cateau()
{
    string input = "<Zoo xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" "
        + "xmlns=\"http://schemas.datacontract.org/2004/07/UnitTestProject3\">"
        + "<anim>Cateau</anim></Zoo>";

    Zoo target = Deserialize<Zoo>(input);
    Assert.IsNotNull(target);
    Assert.AreEqual("Cateau", target.anim);
    Assert.IsNull(target.animAsEnum);
}

[TestMethod]
public void Zoo_Cat()
{
    string input = "<Zoo xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" "
        + "xmlns=\"http://schemas.datacontract.org/2004/07/UnitTestProject3\">"
        + "<anim>Cat</anim></Zoo>";

    Zoo target = Deserialize<Zoo>(input);
    Assert.IsNotNull(target);
    Assert.AreEqual("Cat", target.anim);
    Assert.AreEqual(Animal.Cat, target.animAsEnum);
}

Where Deserialize<T> method is taken from Using DataContractSerializer to serialize, but can't deserialize back

rudolf_franek
  • 1,795
  • 3
  • 28
  • 41
  • Unfortunately, this solution changes wsdl, and j use MessageContract which does not support OnDeserialized. – Jarosław Gosławski Jan 25 '18 at 09:24
  • If the values of enum from the server are not falling into the range defined by enum Animal {} then you are using outdated WSDL, couldn't you just get the up to date WSDL and regenerate your client classes? – rudolf_franek Jan 25 '18 at 10:00
  • WSDL is just definition how to generate server or client classes - it affects only indirectly the data that can be deserialized - please note that in TestMethod Zoo_Cat() you could deserialize class YourOrginalClass { public Anilmal anim{ get; set; } } too without any problem. – rudolf_franek Jan 25 '18 at 10:01
  • OnDeserialized is general functionality not directly related to specific MessageContract, do you confirm, you use WCF? – rudolf_franek Jan 25 '18 at 10:01