6

I encountered a problem when I tried to implement the ServiceKnownType example from MSDN. In the example they provide the following classes:

[DataContract()]
public class Widget
{
    [DataMember]
    public string Id;
    [DataMember]
    public string Catalog;
}

[DataContract()]
public class Machine : Widget
{
    [DataMember]
    public string Maker;
}

And the following interface:

[ServiceKnownType(typeof(Widget))]
[ServiceKnownType(typeof(Machine))]
[ServiceContract()]
public interface ICatalog
{
    [OperationContract]
    Hashtable GetItems();
}

The problem is that when the proxy class is generated (using “Add Service Reference” / svcutil.exe), the “ServiceKnownType” attributes are omitted from the ICatalog proxy interface, resulting in getting an exception “The formatter threw an exception while trying to deserialize the message: … Add the type corresponding to 'Widget' to the list of known types” To solve this problem I have to manually add the service known attributes to the generated proxy interface, which is a very bad solution, since the code regenerates when I update the reference. The interesting thing in all this situation, is that if the GetItems operation would return object instead of Hashtable, or getting an object as a parameter , then the problem would be solved, i.e.

[OperationContract]
object GetItems();

or

[OperationContract]
Hashtable GetItems(object obj);

results in presence of the “ServiceKnownType” attribute on ICatalog proxy interface. Does anyone knows how to solve this problem?

Thanks

Andy
  • 1,153
  • 4
  • 13
  • 33

3 Answers3

1

I spent hours today on what, as best I can tell, is the exact same issue. The solution for me was to use the AddGenericResolver method from IDesign's ServiceModelEx library.

NOTE: .NET 4.0 required as it uses DataContractResolver

You can find it on IDesign Downloads page.

All I had to do in my case was add the following line of code:

Client.AddGenericResolver( typeof ( K2Source ) );

I hope this helps someone else out there save a few hours!

You can find more information in the book "Programming WCF Services: Mastering WCF and the Azure AppFabric Service Bus" by Juval Lowy

Hastarin
  • 345
  • 1
  • 11
0

Problem with ignored ServiceKnownType by svcutil is still here. My solution is add "known types" to client contract reference programmatically:

var client = new ServiceReferenceClient("clientEndpoint");
foreach (var o in client.Endpoint.Contract.Operations)
{
   o.KnownTypes.Add(typeof(MyType01));
   o.KnownTypes.Add(typeof(MyType02));
   o.KnownTypes.Add(typeof(MyType03));
}

It is not perfect solution (must be hard coded on client-side) but it works for me.

Vita
  • 61
  • 4
0

Seems to be a related problem.

Did you try returning generic Dictionary of Widgets and putting [KnownType(typeof(Machine))] on Widget class?

Dmitry Ornatsky
  • 2,237
  • 2
  • 18
  • 25
  • 3
    I want it to work with ServiceKnownType and not with KnownType because in my real-world scenario I can’t add an attribute on the “Widget” class since it’s located in a DLL I can’t change. I would appreciate any other solution for my scenario but I also want to know why the MSDN example doesn’t work – Andy Apr 03 '09 at 08:10