Ramesh
Ramesh

Reputation: 253

C# Soap XML SerializationException while parsing to object

When i try to parse soap xml to objects, i'm getting below exception not sure what i'm doing wrong.

Exception:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll

Additional information: Error in line 1 position 687. Element 'http://soap.sforce.com/2005/09/outbound:sObject' contains data from a type that maps to the name 'urn:sobject.enterprise.soap.sforce.com:Contact'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver if you are using DataContractSerializer or add the type corresponding to 'Contact' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to the serializer.

 static void Main(string[] args)
    {

        string inputString = "<?xml version=\"1.0\" encoding=\"UTF - 8\"?> <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> <soapenv:Body> <notifications xmlns=\"http://soap.sforce.com/2005/09/outbound\"> <SessionId xsi:nil=\"true\"/> <EnterpriseUrl>https://hultibs--FullDev.cs10.my.salesforce.com/services/Soap/c/44.0/00DJ0000003QX7f</EnterpriseUrl> <PartnerUrl>https://hultibs--FullDev.cs10.my.salesforce.com/services/Soap/u/44.0/00DJ0000003QX7f</PartnerUrl> <Notification> <Id>04lJ000000PoRS2IAN</Id> <sObject xsi:type=\"sf:Contact\" xmlns:sf=\"urn:sobject.enterprise.soap.sforce.com\"> <sf:Id>0033600001koT9qAAE</sf:Id> <sf:Email>[email protected]</sf:Email> <sf:Student_ID__c>5192435</sf:Student_ID__c> </sObject> </Notification> </notifications> </soapenv:Body> </soapenv:Envelope>";


        FromXml(inputString);
        Console.ReadLine();
    }

 public static void FromXml(string Xml)
    {
        using (var reader = XmlReader.Create(new StringReader(Xml)))
        {
            Message m = Message.CreateMessage(reader, int.MaxValue, MessageVersion.Soap11);
            var body = m.GetBody<Notifications>();
            Console.WriteLine(body);
        }

    }
[DataContract(Name = "sObject", Namespace = "http://soap.sforce.com/2005/09/outbound")]
    public class SObject
    {
        [DataMember(Name = "Id", Order = 1)]
        public string Id { get; set; }
        [DataMember(Name = "Email", Order = 2)]
        public string Email { get; set; }
        [DataMember(Name = "Student_ID__c", Order = 3)]
        public string Student_ID__c { get; set; }
        [DataMember(Name = "type", Order = 4)]
        public string Type { get; set; }
        [DataMember(Name = "sf", Order = 5)]
        public string Sf { get; set; }
    }

    [DataContract(Name = "Notification", Namespace = "http://soap.sforce.com/2005/09/outbound")]
    public class Notification
    {
        [DataMember(Name = "Id", Order = 1)]
        public string Id { get; set; }
        [DataMember(Name = "sObject", Order = 2)]
        public SObject SObject { get; set; }
    }

    [DataContract(Name = "notifications", Namespace = "http://soap.sforce.com/2005/09/outbound")]
    public class Notifications
    {

        [DataMember(Name = "ActionId", Order = 2)]
        public string ActionId { get; set; }
        [DataMember(Name = "EnterpriseUrl", Order = 3)]
        public string EnterpriseUrl { get; set; }
        [DataMember(Name = "PartnerUrl", Order = 4)]
        public string PartnerUrl { get; set; }
        [DataMember(Name = "Notification", Order = 5)]
        public Notification Notification { get; set; }
    }

Upvotes: 0

Views: 501

Answers (2)

Ackelry Xu
Ackelry Xu

Reputation: 776

You only declare a namespace "http://soap.sforce.com/2005/09/outbound" in your DataContract, you could use Message.CreateMessage to serialize your Notifications and compare your xml with the serialized message.

Below is the code.

static void Main(string[] args)
    {
        Notifications notifications = new Notifications()
        {
            ActionId = "actionId",
            EnterpriseUrl = "enterpriceUri",
            PartnerUrl = "parentUri",
            Notification = new Notification
            {
                Id = "abc",
                SObject = new SObject
                {
                    Email = "email",
                    Id = "id",
                    Sf = "sf",
                    Student_ID__c = "a",
                    Type = "type"
                }
            }
        };
        Message me = Message.CreateMessage(MessageVersion.Soap11, "www.abc.com", notifications);  // create a message and serialize the notifications into the message
        WriteMessage(me, @"d:\message.xml");


    }
    static void WriteMessage(Message message, string fileName)
    {

        using (XmlWriter writer = new XmlTextWriter(fileName, Encoding.UTF8))
        {
            message.WriteMessage(writer);// write the message into a file
        }
        Process.Start(fileName);// show the file
    }

And the serialized messsage.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">www.abc.com</Action></s:Header><s:Body><notifications xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://soap.sforce.com/2005/09/outbound"><ActionId>actionId</ActionId><EnterpriseUrl>enterpriceUri</EnterpriseUrl><PartnerUrl>parentUri</PartnerUrl><Notification><Id>abc</Id><sObject><Id>id</Id><Email>email</Email><Student_ID__c>a</Student_ID__c><type>type</type><sf>sf</sf></sObject></Notification></notifications></s:Body></s:Envelope>

Upvotes: 0

spodger
spodger

Reputation: 1679

The problem, which is described in the exception, is in the following type and namespace declaration for sObject in the soap message

<sObject xsi:type=\"sf:Contact\" xmlns:sf=\"urn:sobject.enterprise.soap.sforce.com\">

because there is no class Contact defined in that namespace (or any other).

If you remove the type and namespace declaration from sObject in the soap message (and remove the sf: prefix from its members) it should work OK.

Or remove the xsi:type=\"sf:Contact\ and change the DataContract to

[DataContract(Name = "sObject", Namespace = "urn:sobject.enterprise.soap.sforce.com")]

Or leave the soap message as it is and change

    [DataContract(Name = "sObject", Namespace = "http://soap.sforce.com/2005/09/outbound")]
    public class SObject

to

    [DataContract(Name = "Contact", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
    public class Contact

also changing (in Notification)

        [DataMember(Name = "sObject", Order = 2)]
        public SObject SObject { get; set; }

to

        [DataMember(Name = "sObject", Order = 2)]
        public Contact SObject { get; set; }

Upvotes: 1

Related Questions