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?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
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();
}
}
回答2:
If you want to be able to pass arbitrary XML on the wire the best way to do it is to use XElement rather than XmlDocument
XmlDocument isn't serializable