Why is my WCF Data Services method not appearing in the OData collections list? - wcf

When I view the root of my WCF Data Services service (http://localhost/MyService.svc/) in a browser I see this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<service xml:base="http://localhost/MyService.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
<workspace>
<atom:title>Default</atom:title>
</workspace>
</service>
I would expect to see a list of collections.
When I go to the $metadata URL I see this:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0">
<Schema Namespace="MyApp" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/05/edm">
<ComplexType Name="Package">
<Property Name="Id" Type="Edm.String" Nullable="true" />
</ComplexType>
</Schema>
<Schema Namespace="MyApp" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/05/edm">
<EntityContainer Name="PackageService" m:IsDefaultEntityContainer="true">
<FunctionImport Name="GetQueryablePackages" ReturnType="Collection(MyApp.Package)" m:HttpMethod="GET" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Why might my GetQueryablePackages collection not be appearing?
I'm using these access settings:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);

Service operations (the function import in the EDM) is not exposed in the service document. Only entity sets are exposed there.
If you want your data to be exposed in the service document make an entity set out of it. Depending on the provider model this differs. Typically it means exposing a property of type IQueryable on your context class. Note that T has to be an entity type (must have a key).

Can you share the context definition where you have defined the IQueryable <> properties. There are 2 things that come to my mind: First the properties must be of type IQueryable<> or some type that derives from it. Second, the element type refered by the IQueryable<> must be an entity type i.e. they must have key properties declared in them.
Hope this helps.
Thanks
Pratik

Or you can create an extension method like this:
public static class TestEntitiesExtensions
{
public static IEnumerable<Package> GetQueryablePackages(this TestEntities context)
{
var uri = new Uri(context.BaseUri, "GetQueryablePackages");
return context.Execute<Package>(uri);
}
}

Related

HTTPClient.PostAsync<T> with XmlMediaTypeFormatter serialization attributes being ignored

I'm working with an existing xsd which looks something like this (shortened for brevity):
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://www.mycompany.com/Widgets"
xmlns="http://www.mycompany.com/Widgets"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="Widget" type="WidgetDefinition" />
<xs:complexType name="WidgetDefinition">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
When you run this through xsd.exe, you get a class definition like:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.mycompany.com/Widgets")]
[System.Xml.Serialization.XmlRootAttribute("Widget", Namespace="http://www.mycompany.com/Widgets", IsNullable=false)]
public partial class WidgetDefinition {
private string nameField;
public string Name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
}
Fast forward ... I'm using HTTPClient to POST to a REST service. The code here is pretty straightforward.
var widget = new WidgetDefinition();
// do something here to hydrate widget
var httpClient = new HttpClient();
return httpClient.PostAsync<WidgetDefinition>(
uri, terminatedCall, new XmlMediaTypeFormatter());
On the receiving end, I want to take the request payload and convert it back to a WidgetDefinition object. If you examine the request content using:
request.Content.ReadAsStringAsync().Result
The xml looks like:
<WidgetDefinition xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.datacontract.org/2004/07/\">
...
Based on the XmlTypeAttribute and XmlRootAttribute attributes on the generated WidgetDefinition class, I expect this to look like:
<Widget xmlns:i=\"http://www.mycompany.com/Widgets\">
...
It appears that the XmlTypeAttribute and XmlRootAttribute attributes are ignored when the serialization is happening on the sending side.
Any clue what could be causing this?
EDIT: If I serialize this manually using XmlSerializer, it obeys the serialization attributes on the WidgetDefinition class. I think my issue has to do with the formatter being passed to the PostAsync call.
From this xmlns=\"http://schemas.datacontract.org/2004/07/\" it appears that your REST service is configured to use DataContractSerializer (the default in a WCF service) and not XmlSerializer.
You can configure your service to use XmlSerializer instead which should at least get you further along:
http://msdn.microsoft.com/en-us/library/ms733901.aspx

WCF: Element has already been exported error

I've acquired more information since the original post and have been able to recreate the problem in a very simple File > New Project > WCF Service Application solution. As a result I'm heavily editing the original content of this post to get rid of some of the superfluous information and simplify the examples:
We have a message contract defined as follows.
[MessageContract( WrapperName = "SingleTypeResponse", WrapperNamespace = "urn:WcfService1" )]
public class SingleTypeResponse<T>
{
[MessageBodyMember( Name = "ReturnValue" )]
public T ReturnValue { get; set; }
}
The service interface has the following:
[OperationContract]
SingleTypeResponse<string> GetStringData();
[OperationContract]
SingleTypeResponse<int> GetIntData();
When I run the project and navigate to the .svc file I get the following:
An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
contract: http://tempuri.org/:IService1 ----> System.InvalidOperationException: The WcfService1.IService1.GetIntData operation references a message element [urn:WcfService1:SingleTypeResponse] that has already been exported from the WcfService1.IService1.GetStringData operation. You can change the name of one of the operations by changing the method name or using the Name property of OperationContractAttribute. Alternatively, you can control the element name in greater detail using the MessageContract programming model.
If I comment out GetIntData on the interface and test the service using the WCF Test Client, with the WrapperName property set, I get the following response XML:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<SingleTypeResponse xmlns="urn:WcfService1">
<ReturnValue xmlns="http://tempuri.org/">foo</ReturnValue>
</SingleTypeResponse>
</s:Body>
</s:Envelope>
I'm guessing that element is the source of the problem, it sees two versions of the same element, one with a string and one with an int.
I then uncommented the GetIntData and removed the WrapperName property from the MessageContract:
[MessageContract( WrapperNamespace = "urn:WcfService1" )]
public class SingleTypeResponse<T>
{
[MessageBodyMember( Name = "ReturnValue" )]
public T ReturnValue { get; set; }
}
I get the same error message with the exception that the message element it's complaining about is the ReturnValue property of the contract rather than the message contract name.
Once again commenting out GetIntData and testing with WCF Test Client I get:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<SingleTypeResponseOf_String xmlns="urn:WcfService1">
<ReturnValue xmlns="http://tempuri.org/">foo</ReturnValue>
</SingleTypeResponseOf_String>
</s:Body>
</s:Envelope>
So I'm able to get it to create a unique name for the wrapper, but the fact that SingleTypeResponseOf_String and SingleTypeResponseOf_Int32 both have a ReturnValue property continues to cause it to blow its brains out.
I've never thought about it before but it makes sense that generic types need to be defined as concrete types for a WSDL. Coming from that perspective, it appears that yes - you are defining two 'types' of SingleTypeResponse in your service. WSDL does not allow two element definitions of the same name & namespace to coexist (for obvious reasons - they need to be uniquely identifiable).
There are a couple of potential conflicts here. I think you've identified the first one - an element named SingleTypeResponse within the urn:WcfService1 namespace. When you turn off the naming of the message contract (allowing it to be named by the serializer) you see the below:
<!-- Setting wrapper name & wrapper namespace -->
<wsdl:message name="SingleTypeResponseOf_String">
<wsdl:part name="parameters" element="q1:SingleTypeResponse"
xmlns:q1="urn:WcfService1" />
</wsdl:message>
<!-- Setting wrapper namespace only -->
<wsdl:message name="SingleTypeResponseOf_String">
<wsdl:part name="parameters" element="q1:SingleTypeResponseOf_String"
xmlns:q1="urn:WcfService1" />
</wsdl:message>
This should avoid the first conflict, because running your two operations means that you'll be able to have two types of element (SingleTypeResponseOf_String and SingleTypeResponseOf_Int).
I believe your second conflict comes from the MessageBodyMember attribute. Because both the operations define messages in the same namespace, and both return types contain an element ReturnValue, you will get a conflict where the urn:ReturnValue element is defined twice, once as an int and once as a string.
To demonstrate see the following, with the GetIntData operation comment out, see the ReturnValue element defined:
<!-- from the XSD http://localhost/Service1.svc?xsd=xsd0 -->
<xs:element name="SingleTypeResponseOf_String">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="q1:ReturnValue"
xmlns:q1="http://tempuri.org/" />
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- from the XSD http://localhost/Service1.svc?xsd=xsd2 -->
<xs:schema elementFormDefault="qualified"
targetNamespace="http://tempuri.org/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://tempuri.org/">
<xs:element name="ReturnValue"
nillable="true"
type="xs:string" />
</xs:schema>
How can you allow the MessageContract to rename the ReturnValue property? I don't think you can with DataContractSerializer.
What's the solution? Well, I don't think there is a solution using [MessageBodyMember]. If you use [DataMember] it will work fine. You mentioned before that you're using net.tcp, so I assume your .NET to .NET. Do you need to exercise that level of control of the SOAP envelopes?
Normally I use DataContract as much as possible, and only venture into MessageContract when necessary - interfacing with older SOAP style platforms.

Injecting Correct ISessionFactory Into IRepository Using Castle Windsor and NHibernate Facility

I have three SQL Server databases that a single application retrieves data from. I am using NHibernate to retrieve data from the different databases. I have things set up so that each database has its own repository and class mappings in its own assembly. In my castle.config file I have the database connections setup using the Castle NHibernate Facility:
<?xml version="1.0" encoding="utf-8" ?>
<castle>
<facilities>
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.Windsor" />
<facility id="nhibernate" isWeb="false" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
<factory id="databaseone.factory" alias="databaseone">
<settings>
<!--Settings Here -->
</settings>
<assemblies>
<assembly>DAL.DatabaseOne</assembly>
</assemblies>
</factory>
<factory id="databasetwo.factory" alias="databasetwo">
<settings>
<!--Settings Here -->
</settings>
<assemblies>
<assembly>DAL.DatabaseTwo</assembly>
</assemblies>
</factory>
<factory id="databasethree.factory" alias="databasethree">
<settings>
<!--Settings Here -->
</settings>
<assemblies>
<assembly>DAL.DatabaseThree</assembly>
</assemblies>
</factory>
</facility>
</facilities>
</castle>
All of my repositories have a constructor that take an ISessionFactory as the parameter:
public MyRepository<T> : IRepository<T>
{
public MyRepository(ISessionFactory factory)
{
//Do stuff here
}
}
I have an installer class where I would like to define the various repositories:
//In install method of IWindsorInstaller
container.register(Component.For(typeof(IRepository<>)).ImplementedBy(typeof(MyRepository<>));
Using one database things work fine. When I add the second database to the mix, the same ISessionFactory is injected into all of the repositories. My question is what is the best way to handle this? I could manually specify which ISessionFactory should be injected into which Repository<> but I cannot seem to find documentation on this. The best way would be if I could say something like: For all class mappings in assembly DAL.DatabaseOne, always inject the ISessionFactory corresponding to databaseone.factory; and for all class mappings in assembly DAL.DatabaseTwo, always inject the ISessionFactory corresponding to databasetwo.factory.
Thoughts or suggestions?
This is explained in this post by Fabio Maulo toward the end under the heading 'Configuring your DAOs/Repository for multiple DB'.
He maps the factory individually for each domain class but you could also use reflection on each of the domain assemblies in your case to register the appropriate factory.

Why does the XmlRoot attribute gets ignored in WCF and how to overcome this

We've observed that when we expose a WCF service which uses classes decorated with various xml serialisation attributes, despite the fact that we use the XmlSerializerFormat attribute on the interface any XmlRoot attribute on any of the operation's parameters gets completely ignored.
The namespace of the parameters is always that of the service and not what we specify.
This is causing us problems as it does not seem to be backwards compatible with ASMX and also because we're using BizTalk, and need to have tighter control over the shape of the XML's exchanged.
A few questions then -
Anybody knows what is the rationale
behind this decision?
Anybody knows
how this is happening? I was under
the impressions that WCF, with the
XmlSerializerFormat attribute, uses
the XmlSerialiser to serialise the
types, which would suggest XmlRoot
should be taken into account, how
come this is not the case? (is it
only due to the fact that, taking
the SOAP envelope into account, the
parameter is not root?)
Most
importantly - anybody knows if
there's a way to 'force the issue' -
i.e. get the parameters to be of the
namespace of our choosing?
I've seen this post, but I don't believe it is relevant to my question -
As per Wagner Silveira's request - the contracts I used to test this are -
[ServiceContract(Namespace = "http://servicecontract"),
XmlSerializerFormat(Style = OperationFormatStyle.Document)]
public interface ITestService
{
[OperationContract]
MyOtherType MyTestMethod(MyType obj);
}
// Composite class for DCS and XMLS
[Serializable, XmlType, XmlRoot(Namespace = "http://datacontract")]
public class MyType
{
[XmlAttribute]
public string StringValue { get; set; }
}
// Composite class for DCS and XMLS
[Serializable, XmlType, XmlRoot(Namespace = "http://datacontract")]
public class MyOtherType
{
[XmlAttribute]
public string OtherStringValue { get; set; }
}
I assume you're using SOAP as the message format. In this case, the object you're serializing is not the root of the XML, the soap envelope is. So it makes sense that the XmlRoot would be ignored. By default WCF will create a message contract for you and name the response and it has the namespace of the service. What you can do is create your own message contract to have full control over SOAP.
Create the following two classes:
[MessageContract]
public class MyTestMethodRequest
{
[MessageBodyMember( Namespace = "http://datacontract" )]
public MyType MyType;
}
[MessageContract]
public class MyTestMethodResponse
{
[MessageBodyMember( Namespace = "http://datacontract" )]
public MyOtherType MyOtherType;
}
Then change the signature of your service operation to the following.
[OperationContract]
public MyTestMethodResponse MyTestMethod( MyTestMethodRequest request )
{
return new MyTestMethodResponse {
MyOtherType = new MyOtherType {
OtherStringValue = "bar"
}
};
}
Now if you example the SOAP messages you should see the following:
Request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"
s:mustUnderstand="1">http://servicecontract/TestService/MyTestMethod</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyTestMethodRequest xmlns="http://servicecontract">
<MyType StringValue="foo" xmlns="http://datacontract" />
</MyTestMethodRequest>
</s:Body>
</s:Envelope>
Response
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyTestMethodResponse xmlns="http://servicecontract">
<MyOtherType OtherStringValue="bar" xmlns="http://datacontract" />
</MyTestMethodResponse>
</s:Body>
</s:Envelope>
I don't know why WCF ignores XmlRoot, so I can't answer that part of your question. But I do have a couple ways to solve the problem.
start with WSDL first.
If you have a particular set of XML namespaces you would like to apply to the messages that get sent and receieved, use WSDL and XML Schema to explicitly specify them.
Then, generate the Server-side stub code, or the client-side proxy code, directly from that WSDL via the svcutil.exe tool.
use a custom ServiceHost
The other option open to you, described at this link, is to use a custom ServiceHost that overrides WCF's decision to disregard the XmlRoot or XmlType attributes on message types.
If you choose to go for the WSDL-First approach, the WSDL should look like this:
<?xml version="1.0" encoding="utf-8" ?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:The-Service-namespace"
xmlns:tns="urn:The-Service-namespace"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:n0="urn:The-Request-namespace"
xmlns:n1="urn:The-Response-namespace"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
elementFormDefault= "unqualified"
>
<types>
<s:schema targetNamespace="urn:The-Request-namespace" >
<s:complexType name="Type1">
<s:sequence>
<s:element name="x" minOccurs="1" maxOccurs="1" type="s:string"/>
</s:sequence>
</s:complexType>
<s:element name="Type1" type="n0:Type1" />
</s:schema>
<s:schema targetNamespace="urn:The-Response-namespace" >
<s:complexType name="Type2">
<s:sequence>
<s:element name="x" minOccurs="1" maxOccurs="1" nillable="false" type="s:string"/>
<s:element name="y" minOccurs="1" maxOccurs="1" nillable="false" type="s:int"/>
<s:element name="z" minOccurs="1" maxOccurs="1" nillable="false" type="s:boolean" />
</s:sequence>
</s:complexType>
<s:element name="Type2" type="n1:Type2" />
</s:schema>
</types>
<message name="RequestMessage">
<part name="inPart1" element="n0:Type1" />
</message>
<message name="ResponseMessage">
<part name="outPart1" element="n1:Type2" />
</message>
<portType name="PortTypeName">
<operation name="Method1">
<input message="tns:RequestMessage" />
<output message="tns:ResponseMessage" />
</operation>
</portType>
<binding name="InterfaceName" type="tns:PortTypeName">
<soap:binding
transport="http://schemas.xmlsoap.org/soap/http"
style="rpc" />
<operation name="Method1">
<soap:operation soapAction="" style="document" />
<input> <soap:body use="literal" /> </input>
<output> <soap:body use="literal" /> </output>
</operation>
</binding>
</definitions>
This WSDL is very simple - it defines a single operation, with a single request message and a single response message.
Notice there are three xml namespaces:
urn:The-Service-namespace
used for the element that wraps the request and response - the first element inside the <SOAP:body>
urn:The-Request-namespace
used for the element wrapped inside that request wrapper, which gets deserialized into an instance of Type1.
urn:The-Response-namespace
used for the element wrapped inside that response wrapper, which gets deserialized into an instance of Type2.
If your web services interface is more complicated, has more operations and consequently more request and response message types, you can add more namespaces, if you like, for all those additional types.

WCF: Configuring Known Types

I want to know as to how to configure known types in WCF. For example, I have a Person class and an Employee class. The Employee class is a sublass of the Person class. Both class are marked with a [DataContract] attribute.
I dont want to hardcode the known type of a class, like putting a [ServiceKnownType(typeof(Employee))] at the Person class so that WCF will know that Employee is a subclass of Person.
Now, I added to the host's App.config the following XML configuration:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
<knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
I compiled it, run the host, added a service reference at the client and added some code and run the client. But an error occured:
The formatter threw an exception while
trying to deserialize the message:
There was an error while trying to
deserialize parameter
http://www.herbertsabanal.net:person.
The InnerException message was 'Error
in line 1 position 247. Element
'http://www.herbertsabanal.net:person'
contains data of the
'http://www.herbertsabanal.net/Data:Employee'
data contract. The deserializer has no
knowledge of any type that maps to
this contract. Add the type
corresponding to 'Employee' to the
list of known types - for example, by
using the KnownTypeAttribute attribute
or by adding it to the list of known
types passed to
DataContractSerializer.'. Please see
InnerException for more details.
Below are the data contracts:
[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Person")]
class Person
{
string _name;
int _age;
[DataMember(Name="Name", Order=0)]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataMember(Name="Age", Order=1)]
public int Age
{
get { return _age; }
set { _age = value; }
}
}
[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Employee")]
class Employee : Person
{
string _id;
[DataMember]
public string ID
{
get { return _id; }
set { _id = value; }
}
}
Btw, I didn't use class libraries (WCF class libraries or non-WCF class libraries) for my service. I just plain coded it in the host project.
I guess there must be a problem at the config file (please see config file above). Or I must be missing something. Any help would be pretty much appreciated.
I guess I have found the answer now.
The configuration file I posted above looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
<knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
What I just added was, the Namespace of the Person class and the Employee class. And no need for the longer Version and Culture values.... The correct configuration should be:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="WCFWithNoLibrary.Person, WCFWithNoLibrary">
<knownType type="WCFWithNoLibrary.Employee, WCFWithNoLibrary" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
<system.serviceModel>
.......
</system.serviceModel>
</configuration>
Now it is shorter and makes more sense. But if 3rd party libraries are used, then adding version, culture, publickeytokens would be required.
I know this was answered a long time ago, but, another (maybe more obvious for future programmers) solution:
[KnownType(typeof(SubClass))]
public class BaseClass
Scott
I got this lengthy error message also in another case. I did use the KnownTypeAttribute and had successfully deployed an application which uses WCF.RIA to production. In the second release I added a new subtype, and added the necessary corresponding KnownTypeAttribute (the compiler did not accept it without this attribute - great). What the compiler did accept and what ran on my machine, did not run in production, however. Only in production I got the error mentioned above. Comparing all the uses of the existing subtypes and the new one revealed I had forgotten that WCF.RIA requires the name of the subtype to be used in a name of a method, like GetMySubTypes. So if you get this error after having added the attributes, see whether it's because of WCF.RIAs conventions.