John Cosmas

I must admit, that I'm a newbie when it comes to WCF, so I've been able to create a working HOST and CLIENT, which also happens to talk to each other rather well. I'm at the point now where the application has to grow up a bit, so I'm taking on COLLECTIONS. I would like for someone to post a working example of a HOST which is able to pass a COLLECTION to a CLIENT and I can read the information. My application can read/populate the COLLECTION on the HOST, but it gives me the following error:

An error occurred while receiving the HTTP response to http://localhost:8080/METHWCFSVC1000/NameService/mex. 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.

Here are the other details.

Source: "mscorlib"

I have read and read and read, but I'm not going anywhere with this, so that is why I'm asking for help that I can use immediately instead of more reading and chasing tail AGAIN!. I looked at the following but I've not been able to get my collection to work on the CLIENT.

http://msdn2.microsoft.com/en-us/library/ms752244.aspx

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=732828&SiteID=1

Specifically, I've got a class called CONTACT and it has 3 datamembers (FIRSTNAME, LASTNAME, SSN). I would appreciate insight into this matter. Please be mindful that I don't need to get more confused. Granted that there are many examples/samples, but you can't put them to work like magic. I'm including my code portions so you can see what I've done.

Here is what I have on the HOST

Code Snippet

_

Public Interface IMETHServices

_

Function GetDataTable() As cContactCollection

End Interface

Here is the class in my HOST that populates my COLLECTION

Code Snippet

Public Class METHServices

Implements IMETHServices

Public Function GetDataTable() As cContactCollection Implements IMETHServices.GetDataTable

Dim cobjContact As cContact

Dim cobjCollection As New cContactCollection

Dim pint100Temp As Integer

For pint100Temp = 0 To gdsMETSData.VW_CONTACTS_LOOKUP.Rows.Count - 1

cobjContact = New cContact

With cobjContact

.ContactID = gdsMETSData.VW_CONTACTS_LOOKUP.Rows(pint100Temp).Item(0)

.FullName = gdsMETSData.VW_CONTACTS_LOOKUP.Rows(pint100Temp).Item(1)

.FirstName = gdsMETSData.VW_CONTACTS_LOOKUP.Rows(pint100Temp).Item(2)

.LastName = gdsMETSData.VW_CONTACTS_LOOKUP.Rows(pint100Temp).Item(3)

End With

cobjCollection.Add(cobjContact)

Next

Return cobjCollection

End Function

Here is what happens on the CLIENT

Code Snippet

Imports System

Imports System.Data

Public Class frmClientEditor

Private Sub frmClientEditor_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim pobjClient As clsServiceClient = New clsServiceClient

Dim pobjCollection As cContactCollection

pobjCollection = pobjClient.GetDataTable

MsgBox(pobjCollection.Count)

End Sub

End Class

I would appreciate any and all help. Thank in advance.

John



Re: Windows Communication Foundation (Indigo) Help with WCF Collection

Fabio Cozzolino

Hi John,

first: what web server you are using IIS or integrated
second: which is the base class for your cContactCollection try to use List<cContact> instead cContactCollection
third: if you remove the GetDataTable operation your service works fine

bye





Re: Windows Communication Foundation (Indigo) Help with WCF Collection

John Cosmas

Fabio;

I'm using IIS 5.0 on my local XP workstation since I'm still developing this. I do have a base class, and I've made a copy on the client as well. So, I can actually create a dummy cContact on my client and read it perfectly. But the CLIENT won't accept the same collection from the HOST and just throws me my error. I would appreciate any coding assistance in this matter. So far, I've had no luck with anyone's samples. Thanks for your time, Fabio.

John





Re: Windows Communication Foundation (Indigo) Help with WCF Collection

Brian McNamara - MSFT

First I would enable tracing

http://msdn2.microsoft.com/en-us/library/ms733025.aspx

and see if there are exception details in the trace logs from the server.

Offhand, this sounds like it might be a problem with DataContract KnownTypes and the cContractCollection type....

http://msdn2.microsoft.com/en-us/library/ms730167.aspx






Re: Windows Communication Foundation (Indigo) Help with WCF Collection

John Cosmas

Brian;

Thanks for your response. However, the problem is semi-fixed. Let me explain. I took the KNOWTYPES VB project that comes with SAMPLES, and made some simple additions to test my application requirements. I added a DATASET to it with a new table called TBL_CONTACTS. So here is what my code ended up looking like.

On the HOST side, I added my GETCONTACT function so simulate sending my CONTACT object to the client. Here is what the updated SERVICE.VB looks like; and you can see how I've defined my CONTACT object. In my particular example, I've deliberately added a RECORD ADD features to see if/when I fire my DIVIDE function, I will actually see that the step has been executed when it adds the CONTACT record into my table. I wrote a simple FORM which queries the CONTACT table and I can see that it has CONTROL records that I've added before the DIVIDE or the GETCONTACT functions ever gets executed.

Code Snippet

' Copyright (c) Microsoft Corporation. All Rights Reserved.

Imports System

Imports System.ServiceModel

Imports System.Runtime.Serialization

Namespace Microsoft.ServiceModel.Samples

' Define a service contract.

< FONT>"http://Microsoft.ServiceModel.Samples")> _

Public Interface IDataContractCalculator

_

Function Add(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber

_

Function Subtract(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber

_

Function Multiply(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber

_

Function Divide(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber

_

Function GetContact() As cContact

End Interface

'Define the data contract for a complex number

'Indicate that ComplexNumberWithMagnitude may be used in place of ComplexNumber

< FONT>"http://Microsoft.ServiceModel.Samples")> _

<KNOWNTYPE(< FONT>GetType(cContact))> _

Public Class cContact

_

Private fContactID As Integer

_

Private fFirstName As String

_

Private fLastName As String

Public Sub New(ByVal mContactID As Integer, ByVal mFirstName As String, ByVal mLastName As String)

With Me

.ContactID = mContactID

.FirstName = mFirstName

.LastName = mLastName

End With

End Sub

Public Property ContactID() As Integer

Get

Return fContactID

End Get

Set(ByVal value As Integer)

fContactID = value

End Set

End Property

Public Property FirstName() As String

Get

Return fFirstName

End Get

Set(ByVal value As String)

fFirstName = value

End Set

End Property

Public Property LastName() As String

Get

Return fLastName

End Get

Set(ByVal value As String)

fLastName = value

End Set

End Property

End Class

'Define the data contract for a complex number

'Indicate that ComplexNumberWithMagnitude may be used in place of ComplexNumber

< FONT>"http://Microsoft.ServiceModel.Samples")> _

<KNOWNTYPE(< FONT>GetType(ComplexNumberWithMagnitude))> _

Public Class ComplexNumber

_

Private realField As Double

_

Private imaginaryField As Double

Public Sub New(ByVal r1 As Double, ByVal i1 As Double)

Me.Real = r1

Me.Imaginary = i1

End Sub

Public Property Real() As Double

Get

Return realField

End Get

Set(ByVal value As Double)

realField = value

End Set

End Property

Public Property Imaginary() As Double

Get

Return imaginaryField

End Get

Set(ByVal value As Double)

imaginaryField = value

End Set

End Property

End Class

'Define the data contract for ComplexNumberWithMagnitude

< FONT>"http://Microsoft.ServiceModel.Samples")> _

Public Class ComplexNumberWithMagnitude

Inherits ComplexNumber

Public Sub New(ByVal real As Double, ByVal imaginary As Double)

MyBase.New(real, imaginary)

End Sub

_

Public Property Magnitude() As Double

Get

Return Math.Sqrt(Imaginary * Imaginary + Real * Real)

End Get

Set(ByVal value As Double)

Throw New NotImplementedException()

End Set

End Property

End Class

' Service class which implements the service contract.

Public Class DataContractCalculatorService

Implements IDataContractCalculator

Public Function Add(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber _

Implements IDataContractCalculator.Add

'Return the derived type

Return New ComplexNumberWithMagnitude(n1.Real + n2.Real, n1.Imaginary + n2.Imaginary)

End Function

Public Function Subtract(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber _

Implements IDataContractCalculator.Subtract

'Return the derived type

Return New ComplexNumberWithMagnitude(n1.Real - n2.Real, n1.Imaginary - n2.Imaginary)

End Function

Public Function Multiply(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber _

Implements IDataContractCalculator.Multiply

Dim real1 As Double = n1.Real * n2.Real

Dim imaginary1 As Double = n1.Real * n2.Imaginary

Dim imaginary2 As Double = n2.Real * n1.Imaginary

Dim real2 As Double = n1.Imaginary * n2.Imaginary * -1

'Return the base type

Return New ComplexNumber(real1 + real2, imaginary1 + imaginary2)

End Function

Public Function Divide(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber _

Implements IDataContractCalculator.Divide

Dim conjugate As New ComplexNumber(n2.Real, -1 * n2.Imaginary)

Dim numerator As ComplexNumber = Multiply(n1, conjugate)

Dim denominator As ComplexNumber = Multiply(n2, conjugate)

Dim pobjRow As Data.DataRow

With gdsDataSet.TBL_CONTACTS

pobjRow = .NewRow()

pobjRow.Item(1) = "Joe"

pobjRow.Item(2) = "Smith"

.Rows.Add(pobjRow)

End With

'Return the base type

Return New ComplexNumber(numerator.Real / denominator.Real, numerator.Imaginary)

End Function

Public Function GetContact() As cContact _

Implements IDataContractCalculator.GetContact

Dim pobjContact As cContact

pobjContact = New cContact(2, "John", "Cosmas")

Dim pobjRow As Data.DataRow

With gdsDataSet.TBL_CONTACTS

pobjRow = .NewRow()

pobjRow.Item(1) = pobjContact.FirstName

pobjRow.Item(2) = pobjContact.LastName

.Rows.Add(pobjRow)

End With

Return pobjContact

End Function

End Class

End Namespace

On the CLIENT side, I've added my cCONTACT code with the hope that the HOST will return my contact record after it has executed the original CLIENT code. In this way, I will at least get to see that the original code works before I run mine.

Code Snippet

' Copyright (c) Microsoft Corporation. All Rights Reserved.

Imports System

Imports System.ServiceModel

Namespace Microsoft.ServiceModel.Samples

'The service contract is defined in generatedClient.vb, generated from the service by the svcutil tool.

'Client implementation code.

Class Client

Public Shared Sub Main()

' Create a client

Dim client As New DataContractCalculatorClient()

' Call the Add service operation.

Dim value1 As New ComplexNumber()

value1.realField = 1

value1.imaginaryField = 2

Dim value2 As New ComplexNumber()

value2.realField = 3

value2.imaginaryField = 4

Dim result As ComplexNumber = client.Add(value1, value2)

Console.WriteLine("Add({0} + {1}i, {2} + {3}i) = {4} + {5}i", value1.realField, value1.imaginaryField, value2.realField, value2.imaginaryField, result.realField, _

result.imaginaryField)

If TypeOf result Is ComplexNumberWithMagnitude Then

Console.WriteLine("Magnitude: {0}", (DirectCast(result, ComplexNumberWithMagnitude)).Magnitude)

Else

Console.WriteLine("No magnitude was sent from the service")

End If

' Call the Subtract service operation.

value1 = New ComplexNumber()

value1.realField = 1

value1.imaginaryField = 2

value2 = New ComplexNumber()

value2.realField = 3

value2.imaginaryField = 4

result = client.Subtract(value1, value2)

Console.WriteLine("Subtract({0} + {1}i, {2} + {3}i) = {4} + {5}i", value1.realField, value1.imaginaryField, value2.realField, value2.imaginaryField, result.realField, _

result.imaginaryField)

If TypeOf result Is ComplexNumberWithMagnitude Then

Console.WriteLine("Magnitude: {0}", (DirectCast(result, ComplexNumberWithMagnitude)).Magnitude)

Else

Console.WriteLine("No magnitude was sent from the service")

End If

' Call the Multiply service operation.

value1 = New ComplexNumber()

value1.realField = 2

value1.imaginaryField = 3

value2 = New ComplexNumber()

value2.realField = 4

value2.imaginaryField = 7

result = client.Multiply(value1, value2)

Console.WriteLine("Multiply({0} + {1}i, {2} + {3}i) = {4} + {5}i", value1.realField, value1.imaginaryField, value2.realField, value2.imaginaryField, result.realField, _

result.imaginaryField)

If TypeOf result Is ComplexNumberWithMagnitude Then

Console.WriteLine("Magnitude: {0}", (DirectCast(result, ComplexNumberWithMagnitude)).Magnitude)

Else

Console.WriteLine("No magnitude was sent from the service")

End If

' Call the Divide service operation.

value1 = New ComplexNumber()

value1.realField = 3

value1.imaginaryField = 7

value2 = New ComplexNumber()

value2.realField = 5

value2.imaginaryField = -2

result = client.Divide(value1, value2)

Console.WriteLine("Divide({0} + {1}i, {2} + {3}i) = {4} + {5}i", value1.realField, value1.imaginaryField, value2.realField, value2.imaginaryField, result.realField, _

result.imaginaryField)

If TypeOf result Is ComplexNumberWithMagnitude Then

Console.WriteLine("Magnitude: {0}", (DirectCast(result, ComplexNumberWithMagnitude)).Magnitude)

Else

Console.WriteLine("No magnitude was sent from the service")

End If

Dim pobjContact As cContact

pobjContact = New cContact

pobjContact = client.GetContact()

Console.WriteLine()

Console.WriteLine(pobjContact.ContactID)

'Closing the client gracefully closes the connection and cleans up resources

client.Close()

Console.WriteLine()

Console.WriteLine("Press <ENTER> to terminate client.")

Console.ReadLine()

End Sub

End Class

End Namespace

The outcome is that the original code gets executed, but when I get to the part that writes POBJCONTACT.CONTACTID, it returns a 0. Plus, the DIVIDE function should have caused my HOST to add the record JOE SMITH, which never happens. It is puzzling that the function works but my CONTACT table has no added records, and a 0 is returned by the GETCONTACT function.

Brian or Fabio, I would appreciate your help in this matter, so let me know if I need to package my code and send it your way. Thanks for your help so far.

John Cosmas<><><><>