Search code examples
wcfxmldocumentdatacontract

Returning XmlDocument from WCF service not working


I am trying to update some WCF service methods that return strings to return XmlDocument objects. I've tried returning it as-is and encapsulating it in a datacontract object. Either way I'm hitting an error upon attempting to update the service reference. The error suggest encapsulating it in a datacontract with an operations contract which I am doing. Is there a trick to this?


Solution

  • There's a way to return a XmlDocument from WCF, but you need to use the XmlSerializer instead of the default serializer (DataContractSerialier) - the code below shows how it can be done. Having said that, do consider using data transfer objects as mentioned in the comments, unless your scenario really requires a XmlDocument to be transferred.

    public class StackOverflow_8951319
    {
        [ServiceContract]
        public interface ITest
        {
            [OperationContract]
            string Echo(string text);
            [OperationContract, XmlSerializerFormat]
            XmlDocument GetDocument();
        }
        public class Service : ITest
        {
            public string Echo(string text)
            {
                return text;
            }
    
            public XmlDocument GetDocument()
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(@"<products>
      <product id='1'>
        <name>Bread</name>
      </product>
      <product id='2'>
        <name>Milk</name>
      </product>
      <product id='3'>
        <name>Coffee</name>
      </product>
    </products>");
                return doc;
            }
        }
        static Binding GetBinding()
        {
            var result = new WSHttpBinding(SecurityMode.None);
            //Change binding settings here
            return result;
        }
        public static void Test()
        {
            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
            ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
            host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
            host.Open();
            Console.WriteLine("Host opened");
    
            ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
            ITest proxy = factory.CreateChannel();
            Console.WriteLine(proxy.Echo("Hello"));
    
            Console.WriteLine(proxy.GetDocument().OuterXml);
    
            ((IClientChannel)proxy).Close();
            factory.Close();
    
            Console.Write("Press ENTER to close the host");
            Console.ReadLine();
            host.Close();
        }
    }