Click to See Complete Forum and Search --> : Web service & ArrayList


Lars_V_J
March 9th, 2010, 07:23 AM
I tried to play a little with WCF & friends, and wanted to make a web app that contacts a web service, which in turn selects some stuff from the standard Northwind db.

My web service:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Collections;

namespace ClassLibrary1
{
[ServiceContract(Namespace="http://somesite.com")]
public interface IMainClass
{
[OperationContract]
string Hello();

[OperationContract]
ArrayList GetData();
}
public class MainClass : IMainClass
{
public string Hello()
{
return "Hello!";
}
public ArrayList GetData()
{
ArrayList a = new ArrayList();
a.Clear();
CustomersDataClass temp = new CustomersDataClass();
temp.CompanyName = "1";
temp.ContactName = "2";
temp.CustomerID = "3";
a.Add(temp);
temp.CompanyName = "4";
temp.ContactName = "5";
temp.CustomerID = "6";
a.Add(temp);
return a;
}
}
public class CustomersDataClass
{
public string CustomerID, CompanyName, ContactName;
}
}


My Webapp:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ServiceModel;
using System.Collections;

namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
MainClassClient client =
new MainClassClient();
client.Open();
string s = client.Hello();
TextBox1.Text = s;

object [] o = client.GetData();
ArrayList a = new ArrayList(o);
client.Close();
}
}
}


The autogenerated code on the client side (the web app):

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3082
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://somesite.com", ConfigurationName="IMainClass")]
public interface IMainClass
{

[System.ServiceModel.OperationContractAttribute(Action="http://somesite.com/IMainClass/Hello", ReplyAction="http://somesite.com/IMainClass/HelloResponse")]
string Hello();

[System.ServiceModel.OperationContractAttribute(Action="http://somesite.com/IMainClass/GetData", ReplyAction="http://somesite.com/IMainClass/GetDataResponse")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(object[]))]
object[] GetData();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IMainClassChannel : IMainClass, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class MainClassClient : System.ServiceModel.ClientBase<IMainClass>, IMainClass
{

public MainClassClient()
{
}

public MainClassClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}

public MainClassClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public MainClassClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public MainClassClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public string Hello()
{
return base.Channel.Hello();
}

public object[] GetData()
{
return base.Channel.GetData();
}
}


When I try to run it, I cal call the Hello function, but when I use GetData, I get:

Server Error in '/' Application.
An existing connection was forcibly closed by the remote host
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

Source Error:

Line 65: public object[] GetData()
Line 66: {
Line 67: return base.Channel.GetData();
Line 68: }
Line 69: }


Source File: C:\Documents and Settings\jensflar\My Documents\Visual Studio 2008\Projects\WebApplication1\WebApplication1\MainClass.cs Line: 67

Stack Trace:

[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +73
System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) +131

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

[WebException: The underlying connection was closed: An unexpected error occurred on a receive.]
System.Net.HttpWebRequest.GetResponse() +5314029
System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +54

[CommunicationException: An error occurred while receiving the HTTP response to http://localhost:8000/ClassLibrary1/MainClass. 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.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +7596735
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +275
IMainClass.GetData() +0
MainClassClient.GetData() in C:\Documents and Settings\jensflar\My Documents\Visual Studio 2008\Projects\WebApplication1\WebApplication1\MainClass.cs:67
WebApplication1._Default.Page_Load(Object sender, EventArgs e) in C:\Documents and Settings\jensflar\My Documents\Visual Studio 2008\Projects\WebApplication1\WebApplication1\Default.aspx.cs:22
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627


Version Information: Microsoft .NET Framework Version:2.0.50727.3082; ASP.NET Version:2.0.50727.3082


Any ideas?

Thanks in advance.

Lars_V_J
March 9th, 2010, 08:03 AM
Ah... found this old thread:
http://forum.springframework.net/showthread.php?t=5274

I will list my solution here if other people have the same problem.

In short: ArrayList can't be used, one must use List<type> instead,
thus...

Server code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Collections;

namespace ClassLibrary1
{
[ServiceContract(Namespace="http://somesite.com")]
public interface IMainClass
{
[OperationContract]
string Hello();

[OperationContract]
[System.Xml.Serialization.XmlInclude(typeof(CustomersDataClass))]
List<CustomersDataClass> GetData();
}
public class MainClass : IMainClass
{
public string Hello()
{
return "Hello!";
}
public List<CustomersDataClass> GetData()
{
List<CustomersDataClass> a = new List<CustomersDataClass>();
a.Clear();
CustomersDataClass temp = new CustomersDataClass();
temp.CompanyName = "1";
temp.ContactName = "2";
temp.CustomerID = "3";
a.Add(temp);
temp = new CustomersDataClass();
temp.CompanyName = "4";
temp.ContactName = "5";
temp.CustomerID = "6";
a.Add(temp);
return a;
}
}
[Serializable]
public class CustomersDataClass
{
private string _CustomerID, _CompanyName, _ContactName;

public string CustomerID
{
get { return _CustomerID; }
set { _CustomerID = value; }
}

public string CompanyName
{
get { return _CompanyName; }
set { _CompanyName = value; }
}

public string ContactName
{
get { return _ContactName; }
set { _ContactName = value; }
}
}
}


Client code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ServiceModel;
using System.Collections;

namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
MainClassClient client =
new MainClassClient();
client.Open();
string s = client.Hello();
TextBox1.Text = s;
ClassLibrary1.CustomersDataClass[] arr = client.GetData();

client.Close();
}
}
}


Autogenerated proxy class (or whatever it is called) here:

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3082
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ClassLibrary1
{
using System.Runtime.Serialization;


[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="CustomersDataClass", Namespace="http://schemas.datacontract.org/2004/07/ClassLibrary1")]
public partial class CustomersDataClass : object, System.Runtime.Serialization.IExtensibleDataObject
{

private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

private string _CompanyNameField;

private string _ContactNameField;

private string _CustomerIDField;

public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}

[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public string _CompanyName
{
get
{
return this._CompanyNameField;
}
set
{
this._CompanyNameField = value;
}
}

[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public string _ContactName
{
get
{
return this._ContactNameField;
}
set
{
this._ContactNameField = value;
}
}

[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public string _CustomerID
{
get
{
return this._CustomerIDField;
}
set
{
this._CustomerIDField = value;
}
}
}
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://somesite.com", ConfigurationName="IMainClass")]
public interface IMainClass
{

[System.ServiceModel.OperationContractAttribute(Action="http://somesite.com/IMainClass/Hello", ReplyAction="http://somesite.com/IMainClass/HelloResponse")]
string Hello();

[System.ServiceModel.OperationContractAttribute(Action="http://somesite.com/IMainClass/GetData", ReplyAction="http://somesite.com/IMainClass/GetDataResponse")]
ClassLibrary1.CustomersDataClass[] GetData();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IMainClassChannel : IMainClass, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class MainClassClient : System.ServiceModel.ClientBase<IMainClass>, IMainClass
{

public MainClassClient()
{
}

public MainClassClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}

public MainClassClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public MainClassClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public MainClassClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public string Hello()
{
return base.Channel.Hello();
}

public ClassLibrary1.CustomersDataClass[] GetData()
{
return base.Channel.GetData();
}
}

Arjay
March 9th, 2010, 01:25 PM
Or return a raw array.


public CustomersDataClass[] GetData()
{
List<CustomersDataClass> a = new List<CustomersDataClass>();
a.Clear();
CustomersDataClass temp = new CustomersDataClass();
temp.CompanyName = "1";
temp.ContactName = "2";
temp.CustomerID = "3";
a.Add(temp);
temp = new CustomersDataClass();
temp.CompanyName = "4";
temp.ContactName = "5";
temp.CustomerID = "6";
a.Add(temp);
return a.ToArray( );
}


A reason to return a raw array would be for better compatibility with clients that don't know about List<>.