WCF Exception: Type 'MyType' with Data Contract Name 'Some Name' is not Expected

  • Thread starter Thread starter Charles
  • Start date Start date
C

Charles

I am trying to modify a MSDN WCF sample, and am getting this error in my
client app.

"There was an error while trying to serialize parameter
http://Microsoft.ServiceModel.Samples:obj. The InnerException message was
'Type 'Client.Form1' with data contract name
'Form1:http://schemas.datacontract.org/2004/07/Client' is not expected. Add
any types not known statically to the list of known types - for example, by
using the KnownTypeAttribute attribute or by adding them to the list of
known types passed to DataContractSerializer.'. Please see InnerException
for more details."

The WCF project is hosted by a Windows service, and this builds and starts
up successfully.

The sample is the Calculator sample, which works fine except for my
addition. The purpose of the addition is to allow a client to register
itself with the service so that it can receive notifications whilst it is
alive. The service defines the INotify interface, which is implemented by
the client. The client tries to register itself with the service by sending
a reference to itself in the Register call, but this is where I get the
exception.

I have Googled the exception, but none of the answers I have found address
the particular thing I am trying to do, so they don't really make sense in
my context.

I'm not sure how much code to post, but here is the bulk of the Windows
service

<code>
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
void Register(INotify notifiable);
}

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[DataContractFormat()]
public interface INotify
{
void Notify(string s);
}

// Implement the ICalculator service contract in a service class.
public class CalculatorService : ICalculator
{
private INotify m_Notifiable;

// Implement the ICalculator methods.
public double Add(double n1, double n2)
{
double result = n1 + n2;

m_Notifiable.Notify("Done adding");

return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;

m_Notifiable.Notify("Done subtracting");

return result;
}

public void Register(INotify notifiable)
{
// Save for notifications
m_Notifiable = notifiable;
}
}
</code>

Here is the client:

<code>
Public Class Form1

Implements Microsoft.ServiceModel.Samples.INotify

Private Client As CalculatorClient

Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles ConnectButton.Click

' Step 1: Create an endpoint address and an instance of the WCF
Client.
Dim epAddress As New
EndpointAddress("http://localhost:8000/ServiceModelSamples/Service")

Client = New CalculatorClient(New WSHttpBinding(), epAddress)

'Step 2: Call the service operations.
''m_Notifiable = New Notifiable

Client.Register(Me)

ConnectButton.Enabled = False
DisconnectButton.Enabled = True

End Sub

Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles DisconnectButton.Click

' Step 3: Closing the client gracefully closes the connection and
cleans up resources.
Client.Close()

ConnectButton.Enabled = True
DisconnectButton.Enabled = False

End Sub

Public Sub Notify(ByVal s As String) Implements
Microsoft.ServiceModel.Samples.INotify.Notify

Label1.Text = s

End Sub
End Class
</code>

The exception is thrown on the line

Client.Register(Me)

Can anyone suggest a solution?

TIA

Charles
 
Read this:
Shared Types vs Shared Contracts

http://blogs.msdn.com/sowmy/archive/2006/06/06/all-about-knowntypes.aspx



And this:

http://social.msdn.microsoft.com/Fo...9f4-52bc-4fa9-a0ff-c0859e041e85?prof=required



and send me a paypal payment, because that took weeks of my time to figure
that stuff out !!



Charles said:
I am trying to modify a MSDN WCF sample, and am getting this error in my
client app.

"There was an error while trying to serialize parameter
http://Microsoft.ServiceModel.Samples:obj. The InnerException message was
'Type 'Client.Form1' with data contract name
'Form1:http://schemas.datacontract.org/2004/07/Client' is not expected.
Add any types not known statically to the list of known types - for
example, by using the KnownTypeAttribute attribute or by adding them to
the list of known types passed to DataContractSerializer.'. Please see
InnerException for more details."

The WCF project is hosted by a Windows service, and this builds and starts
up successfully.

The sample is the Calculator sample, which works fine except for my
addition. The purpose of the addition is to allow a client to register
itself with the service so that it can receive notifications whilst it is
alive. The service defines the INotify interface, which is implemented by
the client. The client tries to register itself with the service by
sending a reference to itself in the Register call, but this is where I
get the exception.

I have Googled the exception, but none of the answers I have found address
the particular thing I am trying to do, so they don't really make sense in
my context.

I'm not sure how much code to post, but here is the bulk of the Windows
service

<code>
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
void Register(INotify notifiable);
}

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[DataContractFormat()]
public interface INotify
{
void Notify(string s);
}

// Implement the ICalculator service contract in a service class.
public class CalculatorService : ICalculator
{
private INotify m_Notifiable;

// Implement the ICalculator methods.
public double Add(double n1, double n2)
{
double result = n1 + n2;

m_Notifiable.Notify("Done adding");

return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;

m_Notifiable.Notify("Done subtracting");

return result;
}

public void Register(INotify notifiable)
{
// Save for notifications
m_Notifiable = notifiable;
}
}
</code>

Here is the client:

<code>
Public Class Form1

Implements Microsoft.ServiceModel.Samples.INotify

Private Client As CalculatorClient

Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles ConnectButton.Click

' Step 1: Create an endpoint address and an instance of the WCF
Client.
Dim epAddress As New
EndpointAddress("http://localhost:8000/ServiceModelSamples/Service")

Client = New CalculatorClient(New WSHttpBinding(), epAddress)

'Step 2: Call the service operations.
''m_Notifiable = New Notifiable

Client.Register(Me)

ConnectButton.Enabled = False
DisconnectButton.Enabled = True

End Sub

Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles DisconnectButton.Click

' Step 3: Closing the client gracefully closes the connection and
cleans up resources.
Client.Close()

ConnectButton.Enabled = True
DisconnectButton.Enabled = False

End Sub

Public Sub Notify(ByVal s As String) Implements
Microsoft.ServiceModel.Samples.INotify.Notify

Label1.Text = s

End Sub
End Class
</code>

The exception is thrown on the line

Client.Register(Me)

Can anyone suggest a solution?

TIA

Charles
 
PS
Since I just went through this:

[OperationContract]
void Register(INotify notifiable);


The above is where I would start:


From the second url I showed you:

[OperationContract]
[ServiceKnownType(typeof(EmployeeConcrete))]
void AddPerson(IPerson);


What the post says is that you cannot put these into the .config file like
you can KnownType.

So you can either "hard wire" up the Concrete (as seen above with the
EmployeeConcrete)..........

or use the "types.txt" solution in the second post.

.................

Below is how you can wire up KnownType via config. (seen in the first url I
gave you).
You ~~cannot~~ do the same with ServiceKnownType (unless you use the
workaround via the second url I showed you).........<< and this is the magic
nugget of information that will save you hours of trial and error and
googling.

<system.runtime.serialization>

<dataContractSerializer>

<declaredTypes>

<add type="MyCompany.Library.Shape`1,

MyAssembly, Version=2.0.0.0, Culture=neutral,

PublicKeyToken=XXXXXX, processorArchitecture=MSIL">

<knownType type="MyCompany.Library.Circle`1,

MyAssembly, Version=2.0.0.0, Culture=neutral,

PublicKeyToken=XXXXXX, processorArchitecture=MSIL">

<parameter index="0"/>

</knownType>

</add>

</declaredTypes>

</dataContractSerializer>

</system.runtime.serialization>



sloan said:
Read this:
Shared Types vs Shared Contracts

http://blogs.msdn.com/sowmy/archive/2006/06/06/all-about-knowntypes.aspx



And this:

http://social.msdn.microsoft.com/Fo...9f4-52bc-4fa9-a0ff-c0859e041e85?prof=required



and send me a paypal payment, because that took weeks of my time to figure
that stuff out !!



Charles said:
I am trying to modify a MSDN WCF sample, and am getting this error in my
client app.

"There was an error while trying to serialize parameter
http://Microsoft.ServiceModel.Samples:obj. The InnerException message was
'Type 'Client.Form1' with data contract name
'Form1:http://schemas.datacontract.org/2004/07/Client' is not expected.
Add any types not known statically to the list of known types - for
example, by using the KnownTypeAttribute attribute or by adding them to
the list of known types passed to DataContractSerializer.'. Please see
InnerException for more details."

The WCF project is hosted by a Windows service, and this builds and
starts up successfully.

The sample is the Calculator sample, which works fine except for my
addition. The purpose of the addition is to allow a client to register
itself with the service so that it can receive notifications whilst it is
alive. The service defines the INotify interface, which is implemented by
the client. The client tries to register itself with the service by
sending a reference to itself in the Register call, but this is where I
get the exception.

I have Googled the exception, but none of the answers I have found
address the particular thing I am trying to do, so they don't really make
sense in my context.

I'm not sure how much code to post, but here is the bulk of the Windows
service

<code>
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
void Register(INotify notifiable);
}

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[DataContractFormat()]
public interface INotify
{
void Notify(string s);
}

// Implement the ICalculator service contract in a service class.
public class CalculatorService : ICalculator
{
private INotify m_Notifiable;

// Implement the ICalculator methods.
public double Add(double n1, double n2)
{
double result = n1 + n2;

m_Notifiable.Notify("Done adding");

return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;

m_Notifiable.Notify("Done subtracting");

return result;
}

public void Register(INotify notifiable)
{
// Save for notifications
m_Notifiable = notifiable;
}
}
</code>

Here is the client:

<code>
Public Class Form1

Implements Microsoft.ServiceModel.Samples.INotify

Private Client As CalculatorClient

Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles ConnectButton.Click

' Step 1: Create an endpoint address and an instance of the WCF
Client.
Dim epAddress As New
EndpointAddress("http://localhost:8000/ServiceModelSamples/Service")

Client = New CalculatorClient(New WSHttpBinding(), epAddress)

'Step 2: Call the service operations.
''m_Notifiable = New Notifiable

Client.Register(Me)

ConnectButton.Enabled = False
DisconnectButton.Enabled = True

End Sub

Private Sub DisconnectButton_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles DisconnectButton.Click

' Step 3: Closing the client gracefully closes the connection and
cleans up resources.
Client.Close()

ConnectButton.Enabled = True
DisconnectButton.Enabled = False

End Sub

Public Sub Notify(ByVal s As String) Implements
Microsoft.ServiceModel.Samples.INotify.Notify

Label1.Text = s

End Sub
End Class
</code>

The exception is thrown on the line

Client.Register(Me)

Can anyone suggest a solution?

TIA

Charles
 
Hi Sloan

Thanks for the reply. I'll look through the posts carefully. From a quick
glance, does it mean that I have to somehow declare the Form1 class to the
service as a known type, or have I misunderstood? If I'm right, I was hoping
to avoid that by having Form1 implement the INotify interface, which the
service _does_ know about, because it defines it.

Charles


sloan said:
Read this:
Shared Types vs Shared Contracts

http://blogs.msdn.com/sowmy/archive/2006/06/06/all-about-knowntypes.aspx



And this:

http://social.msdn.microsoft.com/Fo...9f4-52bc-4fa9-a0ff-c0859e041e85?prof=required



and send me a paypal payment, because that took weeks of my time to figure
that stuff out !!



Charles said:
I am trying to modify a MSDN WCF sample, and am getting this error in my
client app.

"There was an error while trying to serialize parameter
http://Microsoft.ServiceModel.Samples:obj. The InnerException message was
'Type 'Client.Form1' with data contract name
'Form1:http://schemas.datacontract.org/2004/07/Client' is not expected.
Add any types not known statically to the list of known types - for
example, by using the KnownTypeAttribute attribute or by adding them to
the list of known types passed to DataContractSerializer.'. Please see
InnerException for more details."

The WCF project is hosted by a Windows service, and this builds and
starts up successfully.

The sample is the Calculator sample, which works fine except for my
addition. The purpose of the addition is to allow a client to register
itself with the service so that it can receive notifications whilst it is
alive. The service defines the INotify interface, which is implemented by
the client. The client tries to register itself with the service by
sending a reference to itself in the Register call, but this is where I
get the exception.

I have Googled the exception, but none of the answers I have found
address the particular thing I am trying to do, so they don't really make
sense in my context.

I'm not sure how much code to post, but here is the bulk of the Windows
service

<code>
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
void Register(INotify notifiable);
}

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[DataContractFormat()]
public interface INotify
{
void Notify(string s);
}

// Implement the ICalculator service contract in a service class.
public class CalculatorService : ICalculator
{
private INotify m_Notifiable;

// Implement the ICalculator methods.
public double Add(double n1, double n2)
{
double result = n1 + n2;

m_Notifiable.Notify("Done adding");

return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;

m_Notifiable.Notify("Done subtracting");

return result;
}

public void Register(INotify notifiable)
{
// Save for notifications
m_Notifiable = notifiable;
}
}
</code>

Here is the client:

<code>
Public Class Form1

Implements Microsoft.ServiceModel.Samples.INotify

Private Client As CalculatorClient

Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles ConnectButton.Click

' Step 1: Create an endpoint address and an instance of the WCF
Client.
Dim epAddress As New
EndpointAddress("http://localhost:8000/ServiceModelSamples/Service")

Client = New CalculatorClient(New WSHttpBinding(), epAddress)

'Step 2: Call the service operations.
''m_Notifiable = New Notifiable

Client.Register(Me)

ConnectButton.Enabled = False
DisconnectButton.Enabled = True

End Sub

Private Sub DisconnectButton_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles DisconnectButton.Click

' Step 3: Closing the client gracefully closes the connection and
cleans up resources.
Client.Close()

ConnectButton.Enabled = True
DisconnectButton.Enabled = False

End Sub

Public Sub Notify(ByVal s As String) Implements
Microsoft.ServiceModel.Samples.INotify.Notify

Label1.Text = s

End Sub
End Class
</code>

The exception is thrown on the line

Client.Register(Me)

Can anyone suggest a solution?

TIA

Charles
 
You question (after only taking a "quick glance") is very hard to
understand.


I don't like that design at all.

If you want your form to be aware of things (being "Notified"), then you
need to declare a object at the class level and subscribe to its
events........and not wire up the form directly to the interface. What
you're doing (on the surface) seems to be mixing and spaghetti'ing things
together.

All you need to think is "If Form2 needed to be notified, how much duplicate
code would I have"....Your answer would be "Alot". Because you're
spaghetti'ing together the Form1 and the "getting notified".


I would suggest looking at the Observer Design Pattern.
http://www.dofactory.com/Patterns/PatternObserver.aspx
And get a feel for it. That is less about WCF and more about OO design.

Here is a hint (from the dofactory example)

IBM ibm = new IBM("IBM", 120.00);

ibm.Attach(new Investor("Sorros"));

ibm.Attach(new Investor("Berkshire"));





class Investor : IInvestor

Then you could raise events in the Investor class.............and then
have Form1 (or Form2 or Form3) subscribe to those events.







I don't know. You'll have to hash it out, I'm just writing out a few
thoughts...............take what I say with a grain of salt.





The concept is more important than my exact words. "Observer Pattern" over
hardwiring up Form1. <<That's the principal I'm trying to convey.







................



You got some digging to do dude............ A little OO and then some WCF.



But try some things out before asking "at a glance" questions........."at a
glance" questions usually confuse the audience and the originator.



Good luck!







Charles said:
Hi Sloan

Thanks for the reply. I'll look through the posts carefully. From a quick
glance, does it mean that I have to somehow declare the Form1 class to the
service as a known type, or have I misunderstood? If I'm right, I was
hoping to avoid that by having Form1 implement the INotify interface,
which the service _does_ know about, because it defines it.

Charles


sloan said:
Read this:
Shared Types vs Shared Contracts

http://blogs.msdn.com/sowmy/archive/2006/06/06/all-about-knowntypes.aspx



And this:

http://social.msdn.microsoft.com/Fo...9f4-52bc-4fa9-a0ff-c0859e041e85?prof=required



and send me a paypal payment, because that took weeks of my time to
figure that stuff out !!



Charles said:
I am trying to modify a MSDN WCF sample, and am getting this error in my
client app.

"There was an error while trying to serialize parameter
http://Microsoft.ServiceModel.Samples:obj. The InnerException message
was 'Type 'Client.Form1' with data contract name
'Form1:http://schemas.datacontract.org/2004/07/Client' is not expected.
Add any types not known statically to the list of known types - for
example, by using the KnownTypeAttribute attribute or by adding them to
the list of known types passed to DataContractSerializer.'. Please see
InnerException for more details."

The WCF project is hosted by a Windows service, and this builds and
starts up successfully.

The sample is the Calculator sample, which works fine except for my
addition. The purpose of the addition is to allow a client to register
itself with the service so that it can receive notifications whilst it
is alive. The service defines the INotify interface, which is
implemented by the client. The client tries to register itself with the
service by sending a reference to itself in the Register call, but this
is where I get the exception.

I have Googled the exception, but none of the answers I have found
address the particular thing I am trying to do, so they don't really
make sense in my context.

I'm not sure how much code to post, but here is the bulk of the Windows
service

<code>
[ServiceContract(Namespace =
"http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
void Register(INotify notifiable);
}

[ServiceContract(Namespace =
"http://Microsoft.ServiceModel.Samples")]
[DataContractFormat()]
public interface INotify
{
void Notify(string s);
}

// Implement the ICalculator service contract in a service class.
public class CalculatorService : ICalculator
{
private INotify m_Notifiable;

// Implement the ICalculator methods.
public double Add(double n1, double n2)
{
double result = n1 + n2;

m_Notifiable.Notify("Done adding");

return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;

m_Notifiable.Notify("Done subtracting");

return result;
}

public void Register(INotify notifiable)
{
// Save for notifications
m_Notifiable = notifiable;
}
}
</code>

Here is the client:

<code>
Public Class Form1

Implements Microsoft.ServiceModel.Samples.INotify

Private Client As CalculatorClient

Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles ConnectButton.Click

' Step 1: Create an endpoint address and an instance of the WCF
Client.
Dim epAddress As New
EndpointAddress("http://localhost:8000/ServiceModelSamples/Service")

Client = New CalculatorClient(New WSHttpBinding(), epAddress)

'Step 2: Call the service operations.
''m_Notifiable = New Notifiable

Client.Register(Me)

ConnectButton.Enabled = False
DisconnectButton.Enabled = True

End Sub

Private Sub DisconnectButton_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles DisconnectButton.Click

' Step 3: Closing the client gracefully closes the connection and
cleans up resources.
Client.Close()

ConnectButton.Enabled = True
DisconnectButton.Enabled = False

End Sub

Public Sub Notify(ByVal s As String) Implements
Microsoft.ServiceModel.Samples.INotify.Notify

Label1.Text = s

End Sub
End Class
</code>

The exception is thrown on the line

Client.Register(Me)

Can anyone suggest a solution?

TIA

Charles
 
Thanks for the additional comments, welcome if a little harsh.

I am familiar with the pattern, and what I am currently trying to do is not
a million miles from that. Indeed, I am trying to expend a small amount of
energy on this to see if the principle will work, rather than spend a long
time implementing something that will end up being a waste of time. Once I
know it can be done I shall do it properly.

Charles


sloan said:
You question (after only taking a "quick glance") is very hard to
understand.


I don't like that design at all.

If you want your form to be aware of things (being "Notified"), then you
need to declare a object at the class level and subscribe to its
events........and not wire up the form directly to the interface. What
you're doing (on the surface) seems to be mixing and spaghetti'ing things
together.

All you need to think is "If Form2 needed to be notified, how much
duplicate code would I have"....Your answer would be "Alot". Because
you're spaghetti'ing together the Form1 and the "getting notified".


I would suggest looking at the Observer Design Pattern.
http://www.dofactory.com/Patterns/PatternObserver.aspx
And get a feel for it. That is less about WCF and more about OO design.

Here is a hint (from the dofactory example)

IBM ibm = new IBM("IBM", 120.00);

ibm.Attach(new Investor("Sorros"));

ibm.Attach(new Investor("Berkshire"));





class Investor : IInvestor

Then you could raise events in the Investor class.............and then
have Form1 (or Form2 or Form3) subscribe to those events.







I don't know. You'll have to hash it out, I'm just writing out a few
thoughts...............take what I say with a grain of salt.





The concept is more important than my exact words. "Observer Pattern"
over hardwiring up Form1. <<That's the principal I'm trying to convey.







...............



You got some digging to do dude............ A little OO and then some
WCF.



But try some things out before asking "at a glance" questions........."at
a glance" questions usually confuse the audience and the originator.



Good luck!







Charles said:
Hi Sloan

Thanks for the reply. I'll look through the posts carefully. From a quick
glance, does it mean that I have to somehow declare the Form1 class to
the service as a known type, or have I misunderstood? If I'm right, I was
hoping to avoid that by having Form1 implement the INotify interface,
which the service _does_ know about, because it defines it.

Charles


sloan said:
Read this:
Shared Types vs Shared Contracts

http://blogs.msdn.com/sowmy/archive/2006/06/06/all-about-knowntypes.aspx



And this:

http://social.msdn.microsoft.com/Fo...9f4-52bc-4fa9-a0ff-c0859e041e85?prof=required



and send me a paypal payment, because that took weeks of my time to
figure that stuff out !!



I am trying to modify a MSDN WCF sample, and am getting this error in my
client app.

"There was an error while trying to serialize parameter
http://Microsoft.ServiceModel.Samples:obj. The InnerException message
was 'Type 'Client.Form1' with data contract name
'Form1:http://schemas.datacontract.org/2004/07/Client' is not expected.
Add any types not known statically to the list of known types - for
example, by using the KnownTypeAttribute attribute or by adding them to
the list of known types passed to DataContractSerializer.'. Please see
InnerException for more details."

The WCF project is hosted by a Windows service, and this builds and
starts up successfully.

The sample is the Calculator sample, which works fine except for my
addition. The purpose of the addition is to allow a client to register
itself with the service so that it can receive notifications whilst it
is alive. The service defines the INotify interface, which is
implemented by the client. The client tries to register itself with the
service by sending a reference to itself in the Register call, but this
is where I get the exception.

I have Googled the exception, but none of the answers I have found
address the particular thing I am trying to do, so they don't really
make sense in my context.

I'm not sure how much code to post, but here is the bulk of the Windows
service

<code>
[ServiceContract(Namespace =
"http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
void Register(INotify notifiable);
}

[ServiceContract(Namespace =
"http://Microsoft.ServiceModel.Samples")]
[DataContractFormat()]
public interface INotify
{
void Notify(string s);
}

// Implement the ICalculator service contract in a service class.
public class CalculatorService : ICalculator
{
private INotify m_Notifiable;

// Implement the ICalculator methods.
public double Add(double n1, double n2)
{
double result = n1 + n2;

m_Notifiable.Notify("Done adding");

return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;

m_Notifiable.Notify("Done subtracting");

return result;
}

public void Register(INotify notifiable)
{
// Save for notifications
m_Notifiable = notifiable;
}
}
</code>

Here is the client:

<code>
Public Class Form1

Implements Microsoft.ServiceModel.Samples.INotify

Private Client As CalculatorClient

Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles ConnectButton.Click

' Step 1: Create an endpoint address and an instance of the WCF
Client.
Dim epAddress As New
EndpointAddress("http://localhost:8000/ServiceModelSamples/Service")

Client = New CalculatorClient(New WSHttpBinding(), epAddress)

'Step 2: Call the service operations.
''m_Notifiable = New Notifiable

Client.Register(Me)

ConnectButton.Enabled = False
DisconnectButton.Enabled = True

End Sub

Private Sub DisconnectButton_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles DisconnectButton.Click

' Step 3: Closing the client gracefully closes the connection
and cleans up resources.
Client.Close()

ConnectButton.Enabled = True
DisconnectButton.Enabled = False

End Sub

Public Sub Notify(ByVal s As String) Implements
Microsoft.ServiceModel.Samples.INotify.Notify

Label1.Text = s

End Sub
End Class
</code>

The exception is thrown on the line

Client.Register(Me)

Can anyone suggest a solution?

TIA

Charles
 
Charles said:
I am trying to modify a MSDN WCF sample, and am getting this error in my
client app.

"There was an error while trying to serialize parameter
http://Microsoft.ServiceModel.Samples:obj. The InnerException message
was 'Type 'Client.Form1' with data contract name
'Form1:http://schemas.datacontract.org/2004/07/Client' is not expected.
Add any types not known statically to the list of known types - for
example, by using the KnownTypeAttribute attribute or by adding them to
the list of known types passed to DataContractSerializer.'. Please see
InnerException for more details."


You're trying to send a form (class/object) that's a (form) to a WCF
service from a WCF client?

A form in not a serializable WCF data contract decorated with the proper
attributes that makes it such that WCF will accept it as a WCF data
contract and KnownType.

The best you could do was to XML serialize the object to create the
properties of the object in XML and send it as string and cast it back
to a know type on either the client or service side. All behavior of the
object is dropped (methods) and only properties are sent when an object
is sent between the WCF Client/Service.

What are you trying to do here?
 
It doesn't have to be a form I pass. In fact, it wasn't originally, it was
just a simple class object that implemented INotify.

Suppose I had

Class MyClass

Implements INotify

...

End Class

and then in the form had

Dim c as New MyClass

Client.Register(c)

How would I decorate MyClass in order for the client service to accept it?

What I am trying to do is get the mechanism working for passing an object of
type INotify to a WCF service. I could then call methods of INotify, or
later raise events that MyClass would consume.

Charles
 
Charles said:
It doesn't have to be a form I pass. In fact, it wasn't originally, it
was just a simple class object that implemented INotify.

Suppose I had

Class MyClass

Implements INotify

...

End Class

and then in the form had

Dim c as New MyClass

Client.Register(c)

How would I decorate MyClass in order for the client service to accept it?

What I am trying to do is get the mechanism working for passing an
object of type INotify to a WCF service. I could then call methods of
INotify, or later raise events that MyClass would consume.

Charles

You should understand Data Contract basics.

http://msdn.microsoft.com/en-us/library/ms733127.aspx

You should look at the classes/objects in VB and C# in the link that are
valid WCF serialized data contracts decorated properly objects that can
be sent between the WCF client and service.

You can have a class/object that has all kind of methods, events etc,
etc, which is called "behavior" -- behavior of the object. When the WCF
XML serialized data contract object is transmitted between the WCF
client and service, "behavior" is not transmitted, and it is dropped.
Only primitive types in the form of public properties of the object are
sent -- no behavior and only data in public properties are sent.

Or the object can have a collection objects in it that are proper WCF
data contract objects -- decorated correctly with the attributes --
prmitive.

So your object can have the methods, but only primitive data type
properties are going to be transmitted, and object behavior is dropped.

Therefore you must set some kind of primitive public property int, bool,
string, etc that indicates that a notification has been raised. You cast
the WCF data contract object back to its known object type object to
pick-up the behavior and act upon the behavior of the and public
properties of the object.

The known object say it Book.cs is a known object in IServcie as and
object type and to the SVC method something like this.

IService

Book GetBook();

void SaveBook(Book);

SVC Methods

public Book Getbook();
{
var book = dosomethingtogetbook(); // dosomething is returning Book
return book;
}

public void SaveBook(Book as thebook)
{
SaveBook(thebook) // a method
}


Client

var client = new client.

var book = client.GetBook();

You act upon the public properties and behavior of book.

cleint.SaveBook(book);


Of course Book.cs originates on the WCF service side.

HTH
 
sloan said:
Well explained (<< comment geared to Mr. Arnold).

I would point out this 3.5 SP1 specific detail .... since (in your
searching) you'll probably find some older samples.

http://www.pluralsight.com/community/blogs/aaron/archive/2008/05/13/50934.aspx

Now, I am working on WCF Web services and keeping session variables and
cache on the back-end Web servers used by the clients.

Keeping state for an application in the company I work for is like
pulling hen's teeth. I am almost ham-strung with session variables on
the front-end Web servers and not being able to use them.

But may be there is hope yet on the back-end servers through WCF Web
service. -:)
 
Hi, Mr. Arnold,

Now, I am working on WCF Web services and keeping session variables and
cache on the back-end Web servers used by the clients.

Keeping state for an application in the company I work for is like
pulling hen's teeth. I am almost ham-strung with session variables on
the front-end Web servers and not being able to use them.

But may be there is hope yet on the back-end servers through WCF Web
service. -:)

Maybe RESTful APIs could help you with that problem - they are without
session variables by definition.
 
MarkusSchaber said:
Hi, Mr. Arnold,



Maybe RESTful APIs could help you with that problem - they are without
session variables by definition.
.

Can you please elaborate on Restful APIs usage that can maybe help in
keepiing some kind of state between the WCF Web client and WCF Web service?

Like I have a List<T> I held and want to hold in state on the service side.
 
Hi, Ollis,

Can you please elaborate on Restful APIs usage that can  maybe help in
keepiing some kind of state between the WCF Web client and WCF Web service?

Like I have a List<T> I held and want to hold in state on the service side.

The Idea with RESTful APIs is that there is no client specific state
kept on the server at all. No session, no state in RAM.

Every request coming from the client contains all the information
needed to execute that request. So there is no query like "give me the
next 5 Ts from my list", but rather like "give me the Ts with index 6
to 10 from the item list of my invoice no 4711".

This has several implications:
- performant server side implementations provide caching of such data
in RAM, but this is completely transparent to the client.
- for performant client side implementations, the clients must be
"smart" and contain some sort of business logic.
- failover / load balancing to different servers is no problem, as the
server has no session or other client specific state.
- the idea itself is very old - e. G. the classic old "CGI" interface
implemented by forking perl scripts on the server which terminate
after each request make it difficult to store any session context in
the server. Long term data was put to the persistence store, short
term data was often "tunneled" through hidden form fields, so the
client (which were simple http forms without any javascript or other
logic in those days) could resend them with the next request.

HTH,
markus
 
Back
Top