Trouble getting a WCF return a collection to a .NET 2.0 client
hi all,
Can we return a strongly typed collection from a WCF method to a .NET 2.0(ASMX) client.
Thanks
Kiran.
Answers
- Yes, of course. Collections are described in schema (by default) as arrays. So, as long as the array type is also described (using known types in WCF side) the ASMX client can use the WSDL to generate appropriate proxy and client types to serialize.
- You need to ensure that WCF knows how to serialize and deserialize all messages/paramaters used in your operations. This error can be caused by forgetting to apply e.g. [DataContract] to an class used in a message or collection. If you use derived objects you need to use the [ServiceKnownType(typeof(...))] attribute to let WCF know about how to de-/serialize objects not directly references in the operation contracts.
Your operation is returning a List<Object>, how do you expect WCF to know how to serialize the unkown object type ?
When there are nothing to serialize there will be no response message and the connection will be closed by the server.
KjellSJ
All Replies
- Yes, of course. Collections are described in schema (by default) as arrays. So, as long as the array type is also described (using known types in WCF side) the ASMX client can use the WSDL to generate appropriate proxy and client types to serialize.
Thanks Michele.
However there is one issue, shown below is the error that I am getting on the client side when invoking a WCF method call that returns a collection.
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: 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) --- End of inner exception stack trace --- 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) --- End of inner exception stack trace --- at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at CECityCacheService.GetRoleAssigments(Int32 UserID, Boolean UserIDSpecified) in C:\Kiran\CECity\Projects\CECityCachingProxy\CECityCachingProxy\CECityCacheService.cs:line 2640 at CECityCachingClient._Default.Page_Load(Object sender, EventArgs e) in C:\Kiran\CECity\Projects\CECityCachingClient\CECityCachingClient\Default.aspx.cs:line 23 at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at CECityCacheService.GetRoleAssigments(Int32 UserID, Boolean UserIDSpecified) in C:\Kiran\CECity\Projects\CECityCachingProxy\CECityCachingProxy\CECityCacheService.cs:line 2640 at CECityCachingClient._Default.Page_Load(Object sender, EventArgs e) in C:\Kiran\CECity\Projects\CECityCachingClient\CECityCachingClient\Default.aspx.cs:line 23
Thanks
Kiran.
- Do you get the same error if you change the contract from receiving a collection, to receiving a string type? It could be a binding issue, unrelated to the collection. ASMX is only compatible with BasicHttpBinding. ASMX with WSE can be compatible with BasicHttpBinding or WSHttpBinding but in the latter case you have to disable negotiation and possibly even secure sessions.
Michele,
The settings in my config file are already set to "basicHttpBinding" and on changing the contract to recieving a string type, I do not get the above issue.
There are many methods that I am exposing through my WCF service that returns a collection and when I tested one of these methods, I get the error.
Thanks
Kiran.
- Send me a repro and I'll look at it: mlb@dasblonde.net
I am having same issue. below are the details
[
ServiceContract(Namespace="http://www.mymonkey.com/DC/2007/01/01")]public
interface IDCService{
[
OperationContract] List<Object> GetPageData(int maximumRows, int startRowIndex, string PageType);}
public
class DCService : IDCService{
[
OperationBehavior(Impersonation = ImpersonationOption.Required)] public List<Object> GetPageData(int maximumRows, int startRowIndex, string PageType){
PageFactory _PageFactory = new PageFactory(); List<Object> _myList = null; IMyTypes _PgType = _PageFactory.GetMyType(PageType) as IMyTypes ; if (_PgType != null){
_myList =
new List<Object>(); DataSet _ds = _PgType .GetPageData(maximumRows, startRowIndex); if (_ds != null){
int i = 0; foreach (DataRow myDataRow in _ds.Tables[0].Rows){
IdCodeNDescription _IdDesc= new IdCodeNDescription();_IdDesc.Id =
Convert.ToInt16(myDataRow["ID"].ToString()); // Set any integer valu for test purpose._IdDesc.Code =
"Test";_IdDesc.Description =
"Test1"; //Try only with one rec :(( to see if its the number of recs but looks like noif( i ==0)
_myList.Add((Object)_movList);
i++;
}
}
}
return _myList;
}
}
[
DataContract]public
class IdCodeNDescription{
int _Id; string _Desc; string _Code;[
DataMember] public int Id{
get{
return _Id;}
set{
_Id =
value;}
}
[
DataMember] public string Description{
get{
return _Desc;}
set{
_Desc =
value;}
}
[
DataMember] public string Code{
get{
return _Code;}
set{
_Code =
value;}
}
}
web.config
<?
xml version="1.0"?><
configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"><
system.serviceModel><
services><!--
Before deployment, you should remove the returnFaults behavior configuration to avoid disclosing information in exception messages --><
service name="DCService" behaviorConfiguration="CPLServiceBehavior" ><
endpoint contract="IDCService" binding="basicHttpBinding" bindingConfiguration="CPLBinding" /><
endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /></
service></
services><
bindings><
basicHttpBinding><
binding name="CPLBinding" maxReceivedMessageSize="30000"><
security mode="TransportCredentialOnly"><
transport clientCredentialType="Windows"/></
security></
binding></
basicHttpBinding></
bindings><
behaviors><
serviceBehaviors><
behavior name="CPLServiceBehavior"><
serviceDebug includeExceptionDetailInFaults="true" /><
serviceMetadata httpGetEnabled="true" /><
serviceAuthorization impersonateCallerForAllOperations="true"/></
behavior></
serviceBehaviors></
behaviors></
system.serviceModel><
system.web><
compilation debug="true"/></
system.web><
connectionStrings><
add name="DevDB" connectionString=" bla bla bla" providerName="System.Data.SqlClient"/><
add name="MonkeyDB" connectionString="bla bla bla" providerName="System.Data.SqlClient"/></
connectionStrings></
configuration>- You need to ensure that WCF knows how to serialize and deserialize all messages/paramaters used in your operations. This error can be caused by forgetting to apply e.g. [DataContract] to an class used in a message or collection. If you use derived objects you need to use the [ServiceKnownType(typeof(...))] attribute to let WCF know about how to de-/serialize objects not directly references in the operation contracts.
Your operation is returning a List<Object>, how do you expect WCF to know how to serialize the unkown object type ?
When there are nothing to serialize there will be no response message and the connection will be closed by the server.
KjellSJ Perfect!!!!. Thanks for pointing me in the right directio
Adding
[ServiceKnownType(typeof(IdCodeNDescription))]
to the contract resolves the issue
hi Michele
Just wanted to know if you wer able to look into the source that you received. I am also facing the similar issue. My issue is
1) I am have a base entity class marked with Serializable and DataContract attributes.
2) EmployeeEntity is derived from this entity class. This class is also marked with Serializable and DataContract attributes.
3) EntityCollection is a base class implemnting Ilist and ICollection. This collection base class is also marked as Serializable and DataContract attributes.
4) Employees is a collection derived from this EntityCollection and is marked as Serializable and DataContract attributes.
My WCF service Contract has a method called ValidateEmployees as seen below
[
OperationContract][
ServiceKnownType(typeof(Employees))] ArrayList ValidateEmployees(Employees employeesList);However, i am getting an exception unexpected closed connection
Can you help me understand if am missing anyhting here.
Hi thanks a lot. My problem has been resolved.


