Question : WCF Nested complex types

Hi,

I have a problem exposing a class via WCF, when it is referencing another object, which I would like to send "down the wire" as well.
To make it easier, here is a simplified structure that shows the problem:

There are 3 classes: Record (a base class), OnsiteAppointment and Customer (both inherit from Record).

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
  <DataContract()> _
    Public Class OnsiteAppointment
        Inherits Record

        Private _startDate As DateTime
        <DataMember()> _
        Public Property StartDate() As DateTime
            Get
                Return _startDate
            End Get
            Set(ByVal value As DateTime)
                _startDate = value
            End Set
        End Property

Private _customer As Customer
        <DataMember()> _
        Public Property Customer() As Customer
            Get
                Return _customer
            End Get
            Set(ByVal value As Customer)
                _customer = value
            End Set
        End Property

End Class

 <DataContract()> _
    Public Class Customer
        Inherits Record

        Private _firstName As String
        <DataMember()> _
        Public Property FirstName() As String
            Get
                Return _firstName
            End Get
            Set(ByVal value As String)
                _firstName = value
            End Set
        End Property
End Class

<DataContract()> _
Public Class Record

End Class


I try to expose OnsiteAppointment via WCF like this:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
Public Function GetAppointments(ByVal startDate As DateTime, ByVal endDate As DateTime) As List(Of OnsiteAppointment) Implements IOnsiteScheduler.GetAppointments

            Try

                Dim appointments As New List(Of OnsiteAppointment)
...
                    Dim appointment As New OnsiteAppointment
                    appointment.ID = reader("appointmentId")
                    appointment.StartDate = reader.SafeDate("startDate")
                    .                    
                    Dim customer As New Customer
                    customer.FirstName = reader.SafeString("firstName")

                   appointment.Customer = customer
                   appointments.Add(appointment)
                   return appointments
End Function


This works FINE as long as "Customer" doesn't inherit from "Record". Once I make "Customer" inherit from "Record", the following HTTP error is received (client is Silverlight, I got this HTTP error by sniffing the HTTP traffic using "Fiddler2" app):

HTTP/1.1 504 Fiddler - Receive Failure
Content-Type: text/html
Connection: close
Timestamp: 02:37:54.822

ReadResponse() failed: The server did not return a response for this request.                    

...And of course the client fails having received this message.

My question is: What am I doing wrong here?
Obviously "Record" has no problem being exposed, since OnsiteAppointment gets exposed well. There's no problem exposing the nested type (OnsiteAppointment.Customer) as well. So Why would it care if Customer inherits from a type which is working well as a base class for the other class?

Are there any types of restrictions on the level of nesting / referencing other types when returning objects? I would like to refrain from just downloading plain empty collections and then "tying them up" on the client - I'd prefer downloading the object structure just as I have it in the business layer...

Any help would be great!
Thanks

Environment: .NET 4.0, VS 2010, IIS 7, Win7 64bit

Answer : WCF Nested complex types

Hi,

In WCF you cannot substitute a sub class for a base class directly as you can in C#.

You can use an attribute to be able to pass the class to the client. This is done on the Service Interface

KnownType - Allows the class to be passed throughout all contracts and operations using the base class.
This is appliedto the DataContract.
C# : [KnownType(typeof(Customer))]

ServiceKnownType - Allows the class to be passed only for the operation on which it is defined.
This is applied to the Service Contract.

Personally I use ServiceKnownType
C# : [ServiceKnownType(typeof(Customer))]
VB.NET: <ServiceKnownType(GetType(Customer))> _

Have a look here
http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute.aspx

Hope this helps,

Darren
Random Solutions  
 
programming4us programming4us