Microsoft KB Archive/330600

= HOW TO: Use XmlDocument Elements When Passed to or Returned from WebMethods by Using Visual C# .NET =

Article ID: 330600

Article Last Modified on 9/4/2003

-

APPLIES TO


 * Microsoft Visual C# .NET 2002 Standard Edition
 * Microsoft Visual C# .NET 2003 Standard Edition
 * Microsoft Web Services Enhancements for Microsoft .NET 2.0
 * Microsoft Web Services Enhancements for Microsoft .NET 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft .NET Framework 1.1

-



This article was previously published under Q330600



This article refers to the following Microsoft .NET Framework Class Library namespaces:
 * System.Xml



IN THIS TASK

 * SUMMARY
 * Introduction
 * Create a Web Method
 * Consume the Web Method
 * Troubleshoot
 * REFERENCES



SUMMARY
This step-by-step article describes how to write code in .NET applications to execute Web Service methods that take an XmlDocument parameter, or that return an XmlDocument object.

back to the top

Introduction
When XmlDocument objects are passed as parameters to Web Service methods, or are returned from Web Service methods, they are marshaled as XmlNode objects. The XmlDocument and XmlNode types are implemented in the System.Xml namespace (XmlDocument is derived from XmlNode).

If manipulation of the data that is marshaled as an XmlNode (that is passed to a Web Service method, or is returned by a Web Service method) requires that you use the XmlDocument API that is not exposed by the XmlNode type, you must load the data in an XmlDocument object. To do this, use one of the following methods:
 * XmlDocument.LoadXml(XmlNode.OuterXml)
 * XmlDocument.ImportNode(XmlNode, true)

The samples in this article demonstrate how to use these methods

back to the top

Create a Web Method
 In Microsoft Visual Studio .NET, create a new Visual C# .NET ASP.NET Web Service project. To do this, follow these steps:  On the File menu, click New, and then click Project. In the Project Types list, click Visual C# Projects, and then click ASP.NET Web Service in the Templates pane.  In the Location text box, type XMLDocService to change the default name (the default name is WebService1). Change the name of the default Web service that is created from Service1.asmx to XMLDocService.asmx .</li> Click click here to switch to code view in the designer environment to switch to code view.</li> Define a method that returns an XMLDocument object. Each method that the service will expose must be flagged with a WebMethod attribute. Without this attribute, the service will not expose the method.

Note Not every method must have the WebMethod attribute. This attribute can be used to hide some implementation details that are called by public Web service methods or if the WebService class is used in local applications. Although a local application can use any public class, only WebMethod methods can be remotely accessible as XML Web services.</li>  Add the following Web Service methods to the XMLDocService class that you just created: [WebMethod] public XmlDocument GetXmlDocument { // Create an XmlDocument object. XmlDocument xmlDocumentObject = new XmlDocument; XmlDocumentObject.LoadXml(&quot;<book genre=\&quot;novel\&quot; publicationdate=\&quot;1997\&quot; &quot; + &quot;     ISBN=\&quot;1-861001-57-5\&quot;>&quot; + &quot;  Pride And Prejudice &quot; + &quot;  &quot; + &quot;    <first-name>Jane</first-name>&quot; + &quot;    <last-name>Austen</last-name>&quot; + &quot;  &quot; + &quot;  24.95 &quot; + &quot; &quot;);

// Return the created XmlDocument object. return( XmlDocumentObject ); } [WebMethod] public string GetFirstName( XmlNode XmlNodePassed ) { // Create a new XmLDocument object. XmlDocument XmlDocumentObject = new XmlDocument;

// Load the XmlNode into the XmlDocument object. XmlDocumentObject.LoadXml( XmlNodePassed.OuterXml );

// Find the first name of the author. XmlNodeList XmlNodeListObj = XmlDocumentObject.GetElementsByTagName( &quot;first-name&quot; );

// Return the first name. return XmlNodeListObj[ 0 ].ChildNodes[ 0 ].Value; } </li> On the Build menu, click Build Solution to build the Web service.</li> Open the XMLDocService.asmx XML Web service page to test the XML Web service. If you set the local computer to host the page, the URL is http://localhost/XMLDocService/XMLDocService.asmx. The Microsoft ASP.NET runtime returns an XML Web service Help page that describes the XML Web service. You can also use this page to test different XML Web service methods.</li></ol>

back to the top

Consume the Web Method
 In Visual Studio .NET, click New on the File menu, and then click Project.</li> In the Project Types list, click Visual C# Projects, and then click Console Application in the Templates pane.</li> In the new application, add a reference to the XMLDocService Web service.

This step creates a proxy class on the client computer. After the proxy class is created, you can create objects that are based on the class. Each method call that is made with the object is passed to the uniform resource identifier (URI) of the Web service as a SOAP request.  On the Project menu, click Add Web Reference.</li> In the Add Web Reference dialog box, type the URL of the Web service in the Address text box, and then press ENTER. If you set the local computer to host the Web service, the URL is http://localhost/XMLDocService/XMLDocService.asmx.</li> Click Add Reference. Alternatively, you can type the URL of the discovery file (XMLDocService.vsdisco) or click Web References on Local Web Server in the left pane to select the XMLDocService service from the list.</li> Expand the Web References section of Solution Explorer and note the namespace that was used.</li></ol> </li>  Create an instance of the proxy object for the XMLDocService Web service. Paste the following code in the Main function: localhost.XMLDocService myXMLDocService = new localhost.XmlDocService; </li>  To invoke the method of the proxy object, use the following code: XmlDocument myXmlDocumentObject = myXMLDocService.GetXmlDocument; </li> <li>On the Build menu, click Build Solution to build the console application.</li> <li>You receive the following build error message:

Cannot implicitly convert type 'System.Xml.XmlDocument' to 'System.Xml.XmlNode'

</li> <li> Replace the method invocation with the following: XmlNode myXMLNodeObject = myXMLDocService.GetXmlDocument; </li> <li>On the Build menu, click Build Solution to build the console application. You can successfully build the application.</li> <li> Load the data in the returned XmlNode into an XmlDocument object using its ImportNode method: XmlDocument myXmlDocumentObject = new XmlDocument; myXmlDocumentObject.AppendChild(myXmlDocumentObject.ImportNode(myXMLNodeObject,true)); </li> <li> Make a call to the Web Service method that returns the first name of the author: string strFirstName = WebServiceObject.GetFirstName( XmlDocumentObject ); </li> <li> Print the first name of the author on the console: Console.WriteLine( &quot;The first name of the author is: &quot; +strFirstName ); </li> <li>On the Build menu, click Build Solution to build the console application.</li> <li>On the Debug menu, click Run to run the console application.</li></ol>

back to the top

Troubleshoot
If you assign the return value of a Web Service method that returns an XmlDocument object to another XmlDocument object in the client application, you receive the following exception error message:

Cannot implicitly convert type 'System.Xml.XmlNode' to 'System.Xml.XmlDocument'

The error occurs because down-casting is not permitted in Microsoft .NET. The returned XmlDocument is marshaled as an XmlNode. You cannot assign an XmlNode object to an XmlDocument object because XmlDocument is inherited from XmlNode.

Similarly, to expose XmlDocument parameters, you must define the parameters as XmlNode objects. If you declare the parameters as XmlDocument, you receive the following exception error message:

Specified cast is not valid

The exception occurs because the XmlDocument that is passed from the client is marshaled as an XmlNode and the code tries to assign an XmlNode object to an XmlDocument parameter object (down-casting is not permitted in .NET).

back to the top

<div class="references_section">