Reputation: 453
I'm working on creating a WCF Web Service that will either update data in a database or pull data from a database. Right now Im working on the pull portion of this webservice. I've been running into an issue when I try to return a larger data set to the client. Whenever I try testing with the WCF test client I get the following error:
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)
Here is an example of how I have my interface and classes set up:
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;
}
}
}
The thing Im not fully understanding with this error is that when I run the getCutomerName function I get no errors and I can see the resulting xml with all the properties in my customer class in the WCF Test Client, this only happens when I try calling getCustomerData, I'm wondering if it has something to do with me populating more of the properties in the Cust class?
Any help is greatly appreciated!
Update: I've noticed that if I remove the section to populate the custContacts list then I no longer get an error. I realized I pretty much omitted the part where I actually populate the list so I'll update my code here so everyone can see what I'm doing. I also tried making the custContact list just a list of strings but that still throws the error.
Upvotes: 0
Views: 456
Reputation: 453
I found the issue with my code, I had an error with the SQL I was using to grab the custContacts and I was actually grabbing a lot more records than I expected, so I think that was making the object some unreasonable size. I fixed the SQL and I have no issues now.
Upvotes: 1
Reputation: 2252
In the configuration of your WCF binding (in web.config), you need to add maxReceivedMessageSize, or if its there, set it to a larger size.
How to increase maxReceivedMessageSize
http://craigrandall.net/archives/2009/04/maxreceivedmessagesize/
Upvotes: 0