将 XElement 类型作为 WCF 服务中的对象返回时出错
这是我的操作合同:
[ServiceContract]
public interface IService
{
[OperationContract]
object Move();
}
这是操作合同的实现。我想将 XElement 作为对象返回,让客户端将对象转换回 XElement
public object Move()
{
object _x;
var xmlTree1 = new XElement("Root",
new XElement("Child", 1),
new XElement("Child", 2),
new XElement("Child", 3),
new XElement("Child", 4),
new XElement("Child", 5),
new XElement("Child", 6)
);
var xmlTree2 = new XElement("Root",
from el in xmlTree1.Elements()
where ((int) el >= 3 && (int) el <= 5)
select el
);
_x = xmlTree2;
return _x;
}
这是客户端代码:
XElement _xmlelem;
ServiceClient sc = new ServiceClient();
_xmlelem = (XElement)sc.Move();
下面是错误消息的堆栈跟踪:
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.RequestClientReliableChannelBinder`1.OnRequest(TRequestChannel channel, Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at ConsoleApplication1.ServiceReference1.IService.Move()
at ConsoleApplication1.ServiceReference1.ServiceClient.Move() in C:\Delete\ConsoleApplication1\Service References\ServiceReference1\Reference.cs:line 128
at ConsoleApplication1.Program.Main(String[] args) in C:\Delete\ConsoleApplication1\Program.cs:line 20
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Here is my operation contract:
[ServiceContract]
public interface IService
{
[OperationContract]
object Move();
}
Here is the implementation for the operation contract. I want to return XElement as an object, leaving client to convert the object back to XElement
public object Move()
{
object _x;
var xmlTree1 = new XElement("Root",
new XElement("Child", 1),
new XElement("Child", 2),
new XElement("Child", 3),
new XElement("Child", 4),
new XElement("Child", 5),
new XElement("Child", 6)
);
var xmlTree2 = new XElement("Root",
from el in xmlTree1.Elements()
where ((int) el >= 3 && (int) el <= 5)
select el
);
_x = xmlTree2;
return _x;
}
Here is the client code:
XElement _xmlelem;
ServiceClient sc = new ServiceClient();
_xmlelem = (XElement)sc.Move();
Below is the stack strace of the error message:
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.RequestClientReliableChannelBinder`1.OnRequest(TRequestChannel channel, Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at ConsoleApplication1.ServiceReference1.IService.Move()
at ConsoleApplication1.ServiceReference1.ServiceClient.Move() in C:\Delete\ConsoleApplication1\Service References\ServiceReference1\Reference.cs:line 128
at ConsoleApplication1.Program.Main(String[] args) in C:\Delete\ConsoleApplication1\Program.cs:line 20
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您要求 WCF 服务将 .NET 类型(在您的情况下为 XElement)反序列化到发出请求的客户端,然后让客户端将 .NET 对象类型返回值转换为 XElement 类型。 WCF 不支持这种反序列化,除非您通过 使用 NetDataContractSerializer 而不是标准 DataContractSerializer。
使用 NetDataContractSerializer 所以一般来说这不是一个好的做法。我相信您最好直接返回 XML。答案在此问题展示了如何处理数据契约中的XML。
You're asking a WCF service to deserialize a .NET type (XElement in your case) to a requesting client and then have the client cast the .NET object type return value to a XElement type. WCF doesn't support that kind of deserialization unless you configure it for .NET serialization by using the NetDataContractSerializer instead of the standard DataContractSerializer.
There are a lot of constraints to using NetDataContractSerializer so generally it is not a good practice. I believe you'd be better off returning straight XML. The answer in this question shows how to deal with XML in a data contract.