none
WCF服务返回数据时异常!哪位快来帮我. RRS feed

  • 问题

  • 数据库中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:
    2008年1月14日 6:52

答案

  •  

    问题找到了, 造成异常的原因是因为 数据实体类(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);
                        }                   
                    }
                }
            }

     

     

     

    不知道大家有没有碰到相同的问题, 各自又都是如何解决的呢??

     

     

    2008年1月14日 8:45

全部回复

  •  

    问题找到了, 造成异常的原因是因为 数据实体类(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);
                        }                   
                    }
                }
            }

     

     

     

    不知道大家有没有碰到相同的问题, 各自又都是如何解决的呢??

     

     

    2008年1月14日 8:45
  • 非常的感谢!看了你的解决方法 我的问题得到解决
    2011年4月12日 8:06
  • 你好你说的《存在循环引用》是指什么?我现在报的也是这个错,我的实体类只有一个表没有关系表,我这实体里有一个byte【】 我在客户端会调用 WCF将byte保存于HTTP服务器,我现在小文件也可正常成功调用,并返回bool值 ,但传大一点的就报了你说的这种错!这是为什么呢

    2011年4月12日 10:48
  • WCF里面所有的错误都是通信错误,光看这个是不行的。
    快乐在于能够长时间的为自己认为值得的事情努力工作,不管它是什么。
    2011年4月12日 14:26
  • 你好你说的《存在循环引用》是指什么?我现在报的也是这个错,我的实体类只有一个表没有关系表,我这实体里有一个byte【】 我在客户端会调用 WCF将byte保存于HTTP服务器,我现在小文件也可正常成功调用,并返回bool值 ,但传大一点的就报了你说的这种错!这是为什么呢

    请问这个问题你解决了吗?我现在也差不多是这个问题,求解
    2017年9月6日 9:53