Search code examples
c#xmlserializationxml-parsing

Xml Deserizlization


I want to Deserialize the xml to C# class

This is the class which I am using

facing a issue of getting null <sf:Id>12345</sf:Id> this field also added some extra fields like Form_ID__c,Ticket_Id__c,Status. anyone help me to Deserialize this.

[XmlRoot(ElementName = "SessionId")]
public class SessionId
{
    [XmlAttribute(AttributeName = "nil")]
    public bool Nil { get; set; }
}

[XmlRoot(ElementName = "sObject", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
public class SObject
{
    [XmlElement(ElementName = "Id", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
    public string Id { get; set; }
}

[XmlRoot(ElementName = "Notification", Namespace = "http://soap.sforce.com/2005/09/outbound")]
public class Notification
{
    [XmlElement(ElementName = "Id", Namespace = "http://soap.sforce.com/2005/09/outbound")]
    public string Id { get; set; }

    [XmlElement(ElementName = "sObject", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
    public SObject SObject { get; set; }
}

[XmlRoot(ElementName = "notifications", Namespace = "http://soap.sforce.com/2005/09/outbound")]
public class Notifications
{
    [XmlElement(ElementName = "OrganizationId")]
    public string OrganizationId { get; set; }

    [XmlElement(ElementName = "ActionId")]
    public string ActionId { get; set; }

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

    [XmlElement(ElementName = "EnterpriseUrl")]
    public string EnterpriseUrl { get; set; }

    [XmlElement(ElementName = "PartnerUrl")]
    public string PartnerUrl { get; set; }

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

    [XmlAttribute(AttributeName = "xmlns")]
    public string Xmlns { get; set; }
}

[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
    [XmlElement(ElementName = "notifications", Namespace = "http://soap.sforce.com/2005/09/outbound")]
    public Notifications Notifications { get; set; }
}

[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class WebhookModelRequestBody
{
    [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public Body Body { get; set; }
}

sample XML

<?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">
        <OrganizationId>1234</OrganizationId>
        <ActionId>1234</ActionId>
        <SessionId>12222xyshaydfn</SessionId>
        <EnterpriseUrl>https://google.com</EnterpriseUrl>
        <PartnerUrl>https://google.com</PartnerUrl>
        <Notification>
            <Id>12345</Id>
            <sObject xsi:type="sf:Social_Post__c" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
                <sf:Id>12345</sf:Id>
                <sf:Form_ID__c>12345</sf:Form_ID__c>
                <sf:Ticket_Id__c>12345</sf:Ticket_Id__c>
                <sf:Status>Closed</sf:Status>
            </sObject>
        </Notification>
    </notifications>
</soapenv:Body>
 </soapenv:Envelope>

using this sample xml can anyone help me out to Deserialize the xml into c# class


Solution

  • Ok so here is the thing: Im not quite use how you use your xsi, so this will probably still need some edeting. But the jist is: when you define an xsi type it must be a derivative of the type in which you use it. Now in you case since I dont know the details I will just kinda go around it.

    
        [XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Envelope
        {
            [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public Body Body { get; set; }
        }
    
        [XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Body
        {
            [XmlElement(ElementName = "notifications", Namespace = "http://soap.sforce.com/2005/09/outbound")]
            public Notifications Notifications { get; set; }
        }
    
        [XmlRoot(ElementName = "notifications", Namespace = "http://soap.sforce.com/2005/09/outbound")]
        public class Notifications
        {
            [XmlElement(ElementName = "OrganizationId")]
            public string OrgID { get; set; }
            [XmlElement(ElementName = "ActionId")]
            public string ActID { get; set; }
            [XmlElement(ElementName = "SessionId")]
            public string SesID { get; set; }
            [XmlElement(ElementName = "EnterpriseUrl")]
            public string EnterUrl { get; set; }
            [XmlElement(ElementName = "PartnerUrl")]
            public string PartnerUrl { get; set; }
            [XmlElement(ElementName = "Notification")]
            public Notification Notification { get; set; }
    
        }
    
        [XmlRoot(ElementName = "Notification", Namespace = "http://soap.sforce.com/2005/09/outbound")]
        public class Notification
        {
            [XmlElement(ElementName = "Id")]
            public string Id { get; set; }
            [XmlElement(ElementName = "sObject")]
            public SObject SObject { get; set; }
        }
    
        [XmlInclude(typeof(SObjType))]
        [XmlRoot(ElementName = "sObject", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
        public class SObject
        {
            [XmlElement(ElementName = "Id", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
            public string Id { get; set; }
            [XmlElement(ElementName = "Form_ID__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
            public string FromId { get; set; }
            [XmlElement(ElementName = "Ticket_Id__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
            public string TicketId { get; set; }
            [XmlElement(ElementName = "Status", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
            public string Status { get; set; }
        }
    
    
    
        [XmlType(TypeName = "Social_Post__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
        public class SObjType: SObject
        {
    
        }
    
    

    But since you plan on saving this in a sObject type anyway I wonder why we even need to define the SocialPost type. now this could of course be due that coming from the orgiginal serialazation. But since I dont know more details about what you want, this is the best I can give you. But be advides: since the xsi type is a Social Post I assume that the sObject will have less attributes. So this answer should not be seen as fully final but itll give you what you want for now.

    The thing is I assume that sObject is supposed to be a placeholder type from which other things derive so Id, FormId and etc would probably be defined in the SocialPost. So something akin to

    [XmlInclude(typeof(SocialPost))]
    [XmlRoot(ElementName = "sObject", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
    public class SObject
    {
        
    }
    
    
    
    [XmlType(TypeName = "Social_Post__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
    public class SocialPost: SObject
    {
        [XmlElement(ElementName = "Id", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
        public string Id { get; set; }
        [XmlElement(ElementName = "Form_ID__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
        public string FromId { get; set; }
        [XmlElement(ElementName = "Ticket_Id__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
        public string TicketId { get; set; }
        [XmlElement(ElementName = "Status", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
        public string Status { get; set; }
    }
    

    but once you deserialize like this, youll have a sObject type that can be cast into a SocialPost.