积极答复者
WCF服务返回数据时异常!哪位快来帮我.

问题
-
数据库中2个表, Topic(主题表),Comment(评论表).
数据层使用了DLINQ, 并将 Topic 和 Comment 配置成了一对多。
Topic.cs
------------------------------------------------------------
// ..
[DataMember]
[Association(OtherKey="TopicId",Storage="_comments")]
public EntitySet<Comment> Comments
{
get {
return this._comments;
}
set
{
this._comments.Assign(value);
}
}// ..
现在有一个 GetTopics() 方法,用于返回数据库中所有Topic数据,实现如下:
TopicDAL.cs
------------------------------------------------------------
// ..
public List<Topic> GetTopics()
{BlogDataContext Blog = new BlogDataContext();
System.Data.Linq.DataLoadOptions options = new System.Data.Linq.DataLoadOptions();
options.LoadWith<Topic>(p => p.Comments);
Blog.LoadOptions = options;
Blog.Connection.Open();
var topics = (from p in Blog.Topics select p).ToList<Topic>();
if (Blog.Connection.State == System.Data.ConnectionState.Open)
Blog.Connection.Close();
return topics;
}// ..
------------------------------------------------------------
现在的问题是:
当我的客户端程序调用WCF服务的 GetTopics() 方法时就会抛出如下异常.
在服务端调试代码里可以正常看到检索回的数据,但在 return 后,客户端就会出下面异常.
大家帮帮忙,帮我看看吧.. 我小菜鸟在这里先谢了..
异常描述:
接收对 http://localhost:8080/TopicManager 的 HTTP 响应时发生错误。这可能是由于服务终结点绑定未使用 HTTP 协议造成的。这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致。有关详细信息,请参阅服务器日志。
异常详细信息:
未处理 System.ServiceModel.CommunicationException
Message="接收对 http://localhost:8080/TopicManager 的 HTTP 响应时发生错误。这可能是由于服务终结点绑定未使用 HTTP 协议造成的。这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致。有关详细信息,请参阅服务器日志。"
Source="mscorlib"
StackTrace:
Server stack trace:
在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
在 System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
在 System.ServiceModel.Channels.ClientReliableChannelBinder`1.RequestClientReliableChannelBinder`1.OnRequest(TRequestChannel channel, Message message, TimeSpan timeout, MaskingMode maskingMode)
在 System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode)
在 System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout)
在 System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message message, TimeSpan timeout)
在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
在 System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
在 System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
在 WindowsFormsApplication1.ServiceReference.ITopic.GetTopics()
在 WindowsFormsApplication1.ServiceReference.TopicClient.GetTopics() 位置 E:\测试项目\TestSolution\WindowsFormsApplication1\服务引用\ServiceReference\Reference.cs:行号 282
在 WindowsFormsApplication1.Form1.button3_Click(Object sender, EventArgs e) 位置 E:\测试项目\TestSolution\WindowsFormsApplication1\Form1.cs:行号 64
在 System.Windows.Forms.Control.OnClick(EventArgs e)
在 System.Windows.Forms.Button.OnClick(EventArgs e)
在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
在 System.Windows.Forms.Button.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.Run(Form mainForm)
在 WindowsFormsApplication1.Program.Main() 位置 E:\测试项目\TestSolution\WindowsFormsApplication1\Program.cs:行号 18
在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Net.WebException
Message="基础连接已经关闭: 接收时发生错误。"
Source="System"
StackTrace:
在 System.Net.HttpWebRequest.GetResponse()
在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
InnerException: System.IO.IOException
Message="无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接。。"
Source="System"
StackTrace:
在 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
在 System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
在 System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
InnerException: System.Net.Sockets.SocketException
Message="远程主机强迫关闭了一个现有的连接。"
Source="System"
ErrorCode=10054
NativeErrorCode=10054
StackTrace:
在 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
在 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
InnerException:- 已移动 李庆_八爪熊Moderator 2009年5月19日 9:52 ([Loc]From:Windows Vista 开发相关讨论)
答案
-
问题找到了, 造成异常的原因是因为 数据实体类(Topic,Comment) 中存在循环引用, 所以WCF做序列化时会发生异常.
Topic.cs
------------------------------------------------------------
// ..
[DataMember]
[Association(OtherKey="TopicId",Storage="_comments")]
public EntitySet<Comment> Comments
{
get {
return this._comments;
}
set
{
this._comments.Assign(value);
}
}// ..
Comment.cs
------------------------------------------------------------
// [DataMember] (这里又引用回了Topic,注释后便可以正常返回数据)
[Association(ThisKey="TopicId",IsForeignKey=true,Storage="_topic")]
public Topic Topic {
get {
return this._topic.Entity;
}
set
{
Topic previousValue = this._topic.Entity;
if (((previousValue != value)
|| (this._topic.HasLoadedOrAssignedValue == false)))
{
if ((previousValue != null))
{
this._topic.Entity = null;
previousValue.Comments.Remove(this);
}
this._topic.Entity = value;
if ((value != null))
{
value.Comments.Add(this);
this._topicId = value.TopicId;
}
else
{
this._topicId = default(Guid);
}
}
}
}不知道大家有没有碰到相同的问题, 各自又都是如何解决的呢??
全部回复
-
问题找到了, 造成异常的原因是因为 数据实体类(Topic,Comment) 中存在循环引用, 所以WCF做序列化时会发生异常.
Topic.cs
------------------------------------------------------------
// ..
[DataMember]
[Association(OtherKey="TopicId",Storage="_comments")]
public EntitySet<Comment> Comments
{
get {
return this._comments;
}
set
{
this._comments.Assign(value);
}
}// ..
Comment.cs
------------------------------------------------------------
// [DataMember] (这里又引用回了Topic,注释后便可以正常返回数据)
[Association(ThisKey="TopicId",IsForeignKey=true,Storage="_topic")]
public Topic Topic {
get {
return this._topic.Entity;
}
set
{
Topic previousValue = this._topic.Entity;
if (((previousValue != value)
|| (this._topic.HasLoadedOrAssignedValue == false)))
{
if ((previousValue != null))
{
this._topic.Entity = null;
previousValue.Comments.Remove(this);
}
this._topic.Entity = value;
if ((value != null))
{
value.Comments.Add(this);
this._topicId = value.TopicId;
}
else
{
this._topicId = default(Guid);
}
}
}
}不知道大家有没有碰到相同的问题, 各自又都是如何解决的呢??