Parse a soap XML to a C# class

11,120

Try code below. I removed soap from first tag.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication102
{
    class Program
    {

        static void Main(string[] args)
        {
            string responseXml =
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<Envelope" +
                    " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
                    " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
                    " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
                    "<soap:Body>" +
                        "<LoginResponse" +
                            " xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">" +
                            "<LoginResult>" +
                                "<CookieName>FedAuth</CookieName>" +
                                "<ErrorCode>NoError</ErrorCode>" +
                                "<TimeoutSeconds>1800</TimeoutSeconds>" +
                            "</LoginResult>" +
                        "</LoginResponse>" +
                    "</soap:Body>" +
                "</Envelope>";

            XDocument xml = XDocument.Parse(responseXml);
            var soapResponse = xml.Descendants().Where(x => x.Name.LocalName == "LoginResult").Select(x => new SoapResponse()
            {
                CookieName = (string)x.Element(x.Name.Namespace + "CookieName"),
                TimeoutSeconds = (int)x.Element(x.Name.Namespace + "TimeoutSeconds"),
                ErrorCode = (string)x.Element(x.Name.Namespace + "ErrorCode")
            }).FirstOrDefault();

        }

    }
        public class SoapResponse
        {
            public string CookieName { get; set;}
            public int TimeoutSeconds { get; set;}
            public string ErrorCode { get; set;}

        }




}
Share:
11,120

Related videos on Youtube

metal-gogo
Author by

metal-gogo

I believe that the world deserves better software, and it is our responsibility as engineers to improve the web at large.

Updated on September 18, 2022

Comments

  • metal-gogo
    metal-gogo about 1 year

    I'm trying to parse a SOAP message into a specific Class, but I'm having trouble.

    This is the SOAP Message:

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope
        xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
            <LoginResponse
                xmlns="http://schemas.microsoft.com/sharepoint/soap/">
                <LoginResult>
                    <CookieName>FedAuth</CookieName>
                    <ErrorCode>NoError</ErrorCode>
                    <TimeoutSeconds>1800</TimeoutSeconds>
                </LoginResult>
            </LoginResponse>
        </soap:Body>
    </soap:Envelope>
    

    I have a simple class with 3 attributes:

    public class SoapResponse
    {
        public string CookieName { get; set; }
    
        public int TimeoutSeconds { get; set; }
    
        public string ErrorCode { get; set; }
    }
    

    I'm trying to Use Linq to evaluate the Soap XML and parse it into a an object of the SoapResponse Class. So far I have the next code:

    var xml = XDocument.Parse(responseXml);
    var soapResponse = from result in xml.Descendants(XName.Get("LoginResult", xmlNamespace))
        let cookieNameElement = result.Element(XName.Get("CookieName", xmlNamespace)) where cookieNameElement != null
        let timoutSecondsElement = result.Element(XName.Get("TimoutSeconds", xmlNamespace)) where timoutSecondsElement != null
        let errorCodeElement = result.Element(XName.Get("ErrorCode", xmlNamespace)) where errorCodeElement != null
        select new SoapResponse
        {
            CookieName = cookieNameElement.Value,
            TimeoutSeconds = Convert.ToInt32(timoutSecondsElement.Value),
            ErrorCode = errorCodeElement.Value
        };
    

    I know that this is a very similar post to this Using LINQ to XML to Parse a SOAP message post, but I can't find a way to work it around.

    Thanks in advance! :)

  • Leandro Bardelli
    Leandro Bardelli about 4 years
    Add using System.Xml.Linq; and using System.Linq; as reference in order to use this answer.
  • Scott Fraley
    Scott Fraley about 2 years
    What if you can't simply "remove soap from first tag?" I'm dealing with a very similar issue, in that I'm trying to pull the XML out of the 'Body' and I don't have the luxury of simply taking thing(s) out before I have to parse the XML, which starts right off with "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"" etc.
  • jdweng
    jdweng about 2 years
    @ScottFraley : Namespaces are used to perform validation of xml against a schema. Schema checks against xml should be performed by the software that generates the xml. I feel it is silly that users who get xml files from vendor should be doing the checking and then going back to vendor saying they got a bad xml. The vendor should be sending good xml files. So my code simply ignores the namespaces (used for validation of schema) when parsing. The validation should of already been performed.
  • Ângelo Polotto
    Ângelo Polotto about 2 years
    This worked well here, thank you!