0

I have to send Active Directory data to a third-party application. This third-party application provides a .WSDL URL which I have added as a Service Reference in my .NET application. After this I have to call a function "Import" which looks something like this:

Import(Security security, string Data, int FolderID)

Here 'Data' is the XML data that needs to be transferred. I have an XML something like this:

            var xEle = new XElement("Document",
                        from emp in lstADUsers
                        select new XElement("Record",
                                     new XElement("UserName", emp.UserName),
                                       new XAttribute("FirstName", "TEST_FNAME"),
                                       new XAttribute("LastName", "Test_LNAME"),
                                       new XAttribute("Email", "test@test.com")
                                   ));

I call the Import method as:

Import(token, xEle, 1)

When this method is hit, I am getting below error:

The top XML element 'Data' from namespace '' references distinct types System.String and System.Byte[]. Use XML attributes to specify another XML name or namespace for the element or types.

The third-party application expects SOAP data.

Extra details

SOAP envelope looks like this:

<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:sec='http://schemas.xmlsoap.org/ws/2003/06/secext' xmlns:wsu='http://schemas.xmlsoap.org/ws/2003/06/utility' 
xmlns:urn='urn:TestApp'>

   <soapenv:Header>

      <sec:Security>

         <sec:UsernameToken wsu:Id='TestApp'>

            <sec:Username>TestUser</sec:Username>

            <!--Optional:-->

            <sec:Password>TestPassword</sec:Password>

         </sec:UsernameToken>

      </sec:Security>

   </soapenv:Header>

   <soapenv:Body>

     <urn:ImportData>
     <Table></Table>

         <FolderId>0</FolderId>

         <Data><![CDATA[<Document>

         <Record></Record>
</Document>
</Data>

Code Changes Below

 /// <summary>
/// Summary description for ThirdPArtyApp
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]
public class ThirdParty : System.Web.Services.WebService
{

    public Header header;


    [WebMethod]
    [SoapHeader("header", Direction = SoapHeaderDirection.InOut)]
    public void CreateXmlForImport()
    {

   ThirdParty_Serv thirdParty = new ThirdParty_Serv();


        header.Username = "test123";
        header.Password = "XYZ123";

            const string FILENAME = @"D:\Users\Documents\test.xml";
            XDocument doc = XDocument.Load(FILENAME);
            XNamespace nsUrn = doc.Root.GetNamespaceOfPrefix("urn");
            XElement importData = doc.Descendants(nsUrn + "ImportData").FirstOrDefault();
            XElement xCdata = new XElement("Document",
                                    new XElement("Record",
                                     new XAttribute("UserName", "T12345"),
                                       new XAttribute("FirstName", "TEST_RP"),
                                       new XAttribute("LastName", "Test_LNAME"),
                                       new XAttribute("Email", "test@test.com")
                                   ));
        
            string cDataStr = xCdata.ToString();
            XCData cdata = new XCData(cDataStr);

            thirdParty.ImportData("/Do/Persons", 0, cDataStr, 3);

    }
}
RKh
  • 13,818
  • 46
  • 152
  • 265
  • New Element needs a namespace like new XElement(ns + "Record", – jdweng Feb 10 '23 at 13:23
  • Can you please post as answer with details ? It will be easy for me to understand. – RKh Feb 10 '23 at 13:25
  • Post beginning of the soap so I can see the namespaces. – jdweng Feb 10 '23 at 13:59
  • Posted. Also, I added a sample working SOAP data as XML and tried to pass the same to the Import method, it is still throwing the same error. Don't know what it expects. Document says it expects only CDATA. – RKh Feb 10 '23 at 14:25

1 Answers1

1

I used the schema to get correct structure. From VS you can test the syntax by going to menu Project:Add New Item : Xml File. Than past the xml into view. Errors will show like compiler errors in the Error List. Also if you type an opening angle bracket is will show the elements that can be added in any section.

I used following xml

<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:sec='http://schemas.xmlsoap.org/ws/2003/06/secext' xmlns:wsu='http://schemas.xmlsoap.org/ws/2003/06/utility'
xmlns:urn='urn:TestApp'>
    <soapenv:Header>
        <sec:Security>
            <sec:UsernameToken wsu:Id='TestApp'>
                <sec:Username>TestUser</sec:Username>
                <!--Optional:-->
                <sec:Password>TestPassword</sec:Password>
            </sec:UsernameToken>
        </sec:Security>
    </soapenv:Header>
    <soapenv:Body>
        <urn:ImportData>
            <Table></Table>
            <FolderId>0</FolderId>
            <Record></Record>
        </urn:ImportData>
    </soapenv:Body>
</soapenv:Envelope>

Here is my code

        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XNamespace nsUrn = doc.Root.GetNamespaceOfPrefix("urn");
            XElement importData = doc.Descendants(nsUrn + "ImportData").FirstOrDefault();
            XElement xCdata = new XElement("Record",
                                     new XElement("UserName", "username"),
                                       new XAttribute("FirstName", "TEST_FNAME"),
                                       new XAttribute("LastName", "Test_LNAME"),
                                       new XAttribute("Email", "test@test.com")
                                   );
            string cDataStr = xCdata.ToString();
            XCData cdata = new XCData(cDataStr);
            importData.Add(cdata);

        }

Here is final Xml

<?xml version="1.0"?>
<soapenv:Envelope xmlns:urn="urn:TestApp" xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility" xmlns:sec="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <sec:Security>
            <sec:UsernameToken wsu:Id="TestApp">
                <sec:Username>TestUser</sec:Username>
                <!--Optional:-->
                <sec:Password>TestPassword</sec:Password>
            </sec:UsernameToken>
        </sec:Security>
    </soapenv:Header>
    <soapenv:Body>
        <urn:ImportData>
            <Table/>
            <FolderId>0</FolderId>
            <Record/>
            <![CDATA[<Record FirstName="TEST_FNAME" LastName="Test_LNAME" Email="test@test.com"><UserName>username</UserName></Record>]]>
        </urn:ImportData>
    </soapenv:Body>
</soapenv:Envelope>
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • 1
    CData can be in the Record Tag as well as in ImportData. Check to see where the data belongs. – jdweng Feb 10 '23 at 15:49
  • In the original it is before document tag: <![CDATA[ – RKh Feb 13 '23 at 10:16
  • What is the need for "test.xml" you used ? What does it contain? – RKh Feb 13 '23 at 10:19
  • Text.xml is the original xml above. Order in XML doesn't matter. – jdweng Feb 13 '23 at 10:35
  • I am still getting same error. Though I have not tested in a console application. Your method I have added separately. Calling from the method which is giving issues. Shall I remove the [WebMethod] clause and namespace from the calling method ? – RKh Feb 13 '23 at 11:15
  • Initially I added Service Reference of .WSDL under Connected Service. Now I removed it and added Web Reference. In this case, it is giving error: 'Web Service Authentication: Invalid User ID.' – RKh Feb 13 '23 at 12:03
  • Do not remove namespace. I do not know what is wrong. Best think to do is to use VS to help debug issue. From VS menu Project : Add new item : Xml File. Then paste SOAP in the view. Any Schema Errors will show in the Error List like compiler errors. The schema will check for errors. You can also type a open angle bracket and schema will indicate what elements are allowed in each node of the xml. – jdweng Feb 13 '23 at 12:06
  • I have changed the reference to "Web Reference". Not the only error is due to Header. The same issue which is mentioned here: https://stackoverflow.com/questions/3970918/object-reference-not-set-to-an-instance-of-an-object-in-soap – RKh Feb 14 '23 at 11:09
  • Why? That link is from 2010. You were originally getting a namespace issue which mean the Web reference has nothing to do with the issue. The link above would not return any results. You were getting results, just not passing the schema check. The XML you posted isn't providing me enough info to help correctly get correct results. Also the expected output is precise enough to help me get the correct answer. – jdweng Feb 14 '23 at 12:36
  • There were two Import methods. The other one which is now appearing does not accept "Security" parameter which was mentioned in OP. But now it started giving header error. Let me see if I can strip off data and send the entire XML. However, the one I sent you before does contain all the necessary details. – RKh Feb 14 '23 at 17:20
  • Are you referring the HTTP Headers or XML? – jdweng Feb 14 '23 at 17:30
  • Not sure this error is related to what but I am getting same error which is mentioned in this link: https://stackoverflow.com/questions/3970918/object-reference-not-set-to-an-instance-of-an-object-in-soap – RKh Feb 15 '23 at 09:45
  • You are sending an HTTP Request to return xml data. The link is showing solution if authentication is failing. If you are getting XML results in the body than you are passing authentication. If you are not getting results than you need to get the status from the response. A good response is a 200 OK, while errors are normally 400 or 500 status. When you get an error usually the body is empty and doesn't contain xml. – jdweng Feb 15 '23 at 10:06
  • Actually, as of now I have a WebService which holds your code to call "importData" method of third-party appliation. The "header" is coming null. Let me add code with the changes in OP. – RKh Feb 15 '23 at 10:10
  • I have added modified code. As soon as it reaches: header = "Password" field, it gives null reference exception. Probably header not initialized. – RKh Feb 15 '23 at 10:18
  • I am directly executing this WebService code. There is no WebPage from where it is being called. Will move this code to ConsoleApplication. No client application as of now. – RKh Feb 15 '23 at 10:21
  • A Soap Header is the first line of the Soap containing the namespaces. So error MAY mean the schema check is failing. The best way of checking the schema is to past the XML into Visual Studio to make sure it passes. I do not see a default namespace. The default namespace doesn't contain a prefix (like `soapenv') : xmlns='URl'. The default namespace may not be at the beginning of the XML. I will also be used to check the xml elements that do not have a prefix. – jdweng Feb 15 '23 at 10:28
  • There are two types of headers 1) HTTP Headers 2) XML Header. Password is probably the HTTP header with is used for authentication. With SOAP the following occurs in the following sequence 1) Connection is establish. If using HTTPS (secure) a TLS certificate is used to establish connection 2) A Windows authentication will occur. There are many different types of authentication. Some use a username and password on URL, but these are generally obsolete since the password is not encrypted. 3) With SOAP a schema check will be performed including namespace checks on the body of the xml – jdweng Feb 15 '23 at 10:35
  • Continue from above : 4) Additional authentication may be performed on contents of the xml. TRansfer will stop as soon as an error is detected. – jdweng Feb 15 '23 at 10:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251886/discussion-between-rkh-and-jdweng). – RKh Feb 15 '23 at 10:37
  • You are making a HTTP Request/Response. A Webpage is not needed. An HTTP app can be used instead. The webpage is on the client that connects to a HTTP Service on the server. A client can use code instead of a webpage. When you use a browser on the client you connect to a server and the server sends back a response that fills the webpage with data. The webpage can have buttons and when you press a button a second request is sent to the server. You do not need a browser. Same can be done in code. – jdweng Feb 15 '23 at 10:42
  • I don't require a WebPage and a WebService. I just need a Console Application. Will add a Service Reference to the third-party .WSDL. Once that is done, how does the header information be initialized in the method shared above. – RKh Feb 15 '23 at 10:46
  • In the Console Application, you have only "Service Reference". Few methods not available which were showing up in WebService when I added "WebService Reference". – RKh Feb 15 '23 at 11:01
  • Don't know what that means. What is your target? Are you using Core? Sound like and difference between Net and Core. You target version of Net/Core may need changing. – jdweng Feb 15 '23 at 12:55
  • I am using VS2022. In the solution first I added a WebService project which contains your method. Now added a Console project in the solution which is calling the WebService. Referred to the example given in that Wrox link. But now when I am trying to call a method in WebService, it is throwing error: Severity Code Description Project File Line Suppression State Error CS0012 The type 'WebService' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. – RKh Feb 15 '23 at 14:14
  • 1
    Try a clean build. Looks like you changed your target version of Net/Core. Not all the intermediate OBJ files were compiled. Some contain reference to a different version of Net/Core that is not installed. Or a library need to be added to the using statement at top of module and add missing reference. – jdweng Feb 15 '23 at 14:22