将较大的数据集返回给客户端时出现WCF Webservice错误

时间:2017-02-27 16:47:05

标签: c# web-services wcf

我正在创建一个WCF Web服务,它将更新数据库中的数据或从数据库中提取数据。现在我正在研究这个web服务的拉动部分。当我尝试将更大的数据集返回给客户端时,我遇到了一个问题。每当我尝试使用WCF测试客户端进行测试时,我都会收到以下错误:

An error occurred while receiving the HTTP response to http://localhost:56196/CustomerService.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

Server stack trace: 
   at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.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.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 ISylectusCustomerService.getCustomerData(Int32 pabcode, Int16 CompanyCode, String UserName, String Password)
   at SylectusCustomerServiceClient.getCustomerData(Int32 pabcode, Int16 CompanyCode, String UserName, String Password)

Inner Exception:
The underlying connection was closed: An unexpected error occurred on a receive.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

Inner Exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)

Inner Exception:
An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

以下是我如何设置界面和类的示例:

namespace SylectusCustomerWebSrv
{       
    [DataContract]
    public class Customer
    {
        [DataMember]
        public bool customerExists { get; set; }
        [DataMember]
        public string ErrorText { get; set; }
        [DataMember]
        public Cust customer;
        [DataMember]
        public List<CustContact> custContacts;

        public Customer()
        {
            customerExists = false;
            ErrorText = "";
        }
    }

    [DataContract]
    public class Cust
    {
        #region ClassProperties

        [DataMember]
        public string CustomerName{ get; set; }
        //I have a lot more properties here but didnt want to list them all.

        #endregion

        public Cust()
        {

        }
    }

    [DataContract]
    public class CustContact
    {
        #region ClassProperties

        [DataMember]
        public int ContactName{ get; set; }
        //I have a lot more properties here but didnt want to list them all.
        #endregion

        public CustContact() { }

    }

    [ServiceContract]
    [XmlSerializerFormat]
    //note: I'm using xmlserializerformat here so I dont get the specified parameters in my client when I try to call my functions
    public interface ISylectusCustomerService
    {
        [OperationContract]
        Customer getCustomerName(int pabcode, short CompanyCode, string UserName, string Password);

        [OperationContract]
        Customer getCustomerData(int pabcode, short CompanyCode, string UserName, string Password);
    }

    public class SylectusCustomerService : ISylectusCustomerService
    {
        private DatabaseConnection db;  

        private bool UserAllowed(short companyCode, string username, string password)
        {
            bool accessGranted = false;

            try
            {
                //here I check the creds against the database and set accessgranted to either true or false.                
            }
            catch (Exception ex)
            {

            }
            return accessGranted;
        }

        public Customer getCustomerName(int pabcode, short CompanyCode, string UserName, string Password)
        {
             Customer cust = new Customer();
             cust.customer = new Cust();

             cust.ErrorText = "";

             if (!UserAllowed(CompanyCode, UserName, Password))
             {
                 cust.ErrorText = "Invalid Credentials";
                 return cust;
             }
             else
             {
                 try
                 {
                     db = DatabaseConnectionFactory.Instance.OpenDatabaseConnection(CompanyCode);

                     if (db.IsOpen)
                     {
                         custController = new custController (db);
                         cust.customer.CustomerName = custController .GetCustomerName(pabcode, CompanyCode.ToString());
                         db.Close();
                         if (cust.customer.CustomerName.Length == 0)
                         {
                             cust.ErrorText = "No Customer found for PABCode: " + pabcode;
                         }                        
                     }
                     else
                     {
                         cust.ErrorText = "Unable to open database";
                     }                    
                 }
                 catch (Exception ex)
                 {
                cust.ErrorText = "Exception: " + ex.Message;
                 }
                 return cust;
             }
         }

         public Customer getCustomerData(int pabcode, short CompanyCode, string UserName, string Password)
         {
             Customer cust = new Customer();

             cust.ErrorText = "";

             if (!UserAllowed(CompanyCode, UserName, Password))
             {
                 cust.ErrorText = "Invalid Credentials";
             }
             else
             {
                 try
                 {
                     string existingCust = custExists(pabcode, CompanyCode);

                     if (existingCust == "true")
                     {
                         db = DatabaseConnectionFactory.Instance.OpenDatabaseConnection(CompanyCode);

                         if (db.IsOpen)
                         {
                             cust.customer = new Cust();
                             cust.custContacts = new List<CustContact>();

                             //here I do a sql call and grab the customer data and store it in the cust object
                             SelectStatement sql = new SelectStatement();
                             sql.Table(custtable);
                             sql.Column(custName);
                             sql.Where(wherestatement);
                             using (QueryResult res = db.Query(sql))
                             {
                                 if (res.Read())
                                 {
                                     cust.customer.CustomerName = res.GetString("custName");
                                 }
                             }
                             //here I do a sql call and grab the customer contact data and store it in the custContact list **here is where the issue comes up I think.
                             SelectStatement sql = new SelectStatement();
                             sql.Table(custContacttable);
                             sql.Column(custContactName);
                             sql.Where(wherestatement);
                             using (QueryResult res = db.Query(sql))
                             {
                                 if (res.Read())
                                 {
                                     CustContact cc = new CustContact();
                                     pc.ContactName = res.GetString("custContactName");
                                     cust.custContacts.Add(cc);
                                     //if I comment out the previous line then I no longer get the error and the cust.customer object is populated correctly and gets sent to the client.
                                 }
                             }

                             db.Close();
                         }
                         else if (existingCust == "false")
                         {
                             cust.customerExists = false;
                             cust.ErrorText = "No customer exists with pabcode: " + pabcode;
                         }
                         else
                         {
                             cust.customerExists = false;
                             cust.ErrorText = existingCust;
                         }
                     }
                     else
                     {
                         cust.ErrorText = "Unable to open database";
                     }
                 }
                 catch (Exception ex)
                 {
                     cust.ErrorText = "Exception: " + ex.Message;
                 }
             }

             return cust;
         }

         public string custExists(int pabcode, short MABCode)
         {
             string custExists = "false";

             try
             {
                 //function checks database to see if customer exists
             }
             catch (Exception ex)
             {
                 custExists = "Exception: " + ex.Message;
             }

             return custExists;
         }        
     }
}

我对这个错误没有完全理解的是,当我运行getCutomerName函数时,我没有错误,我可以在WCF测试客户端的客户类中看到所有属性的结果xml,这只发生在我尝试调用getCustomerData,我想知道它是否与我在Cust类中填充更多属性有关?

非常感谢任何帮助!

更新:我注意到如果我删除该部分以填充custContacts列表,那么我不再收到错误。我意识到我几乎省略了实际填充列表的部分,所以我在这里更新我的代码,这样每个人都可以看到我在做什么。我还尝试将custContact列表作为字符串列表,但仍然会引发错误。

2 个答案:

答案 0 :(得分:1)

我发现我的代码存在问题,我在使用SQL来获取custContacts时遇到了错误,我实际上抓取了比预期更多的记录,所以我认为这会使对象的大小不合理。我修复了SQL,现在没有问题。

答案 1 :(得分:0)

在WCF绑定的配置中(在web.config中),您需要添加maxReceivedMessageSize,如果在那里,则将其设置为更大的大小。

How to increase maxReceivedMessageSize

http://craigrandall.net/archives/2009/04/maxreceivedmessagesize/

相关问题