WCF MessageContract Inheritance - wcf

I am fairly new to WCF and just have a question on how to correctly get MessageContract inheritance working. A simplified version of my setup is as follows - a "base" message type, and then another "test" message which inherits from it.
[MessageContract]
public abstract class BaseMessage
{ }
[MessageContract]
public class TestMessage : BaseMessage
{ }
I then have an asynchronous OperationContract on a ServiceContract defined as:
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFindRequest(BaseMessage request, AsyncCallback callback, object asyncState);
The problem that I am getting is when calling the BeginFindRequest method, and passing in a TestMessage instance for the request parameter, the WCF framework is deserialising the TestMessage instance to BaseMessage on the service/server side. As this is defined as an abstract class, it results in the following error:
"The message cannot be deserialized
into MessageContract type BaseMessage
since it does not have a default
(parameterless) constructor."
From the limited information that I can find on MessageContract inheritance, it seems that it should just work.
So my question is - what am I missing in order to get this to work; or should I perhaps rather define a seperate OperationContract on the ServiceContract specifically for that type - the downside being that I could end up with many additional OperationContracts?

In the end I found this blog post which hit the nail on the head -
Unfortunately the way that contracts
are expressed in WCF makes is very
easy to forget what their purpose is:
to define the messages send to the
operation and being sent back from the
operation. In reality you have to
think “how would I express this data
in XML?”. XML doesn’t support
inheritance so whatever you put in the
contract is going to have to have some
way of mapping to XML. The data
contracts used to define the messages
are simply a .NET typed convenience
for generating the XML for the data
you want to pass – if you view them
any other way you are destined for a
world of pain. So think about the data
you want to pass, not how it may
happen to be represented in your
business layer and design your
DataContracts accordingly.
http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx
So I will be refactoring to provide an additional method with an explicit contract type. This will also allow me to clean up the service implementation by removing all the type checking.
Thanks for the assistance.

OK, first question is: why are you really using Message contracts? Do you really have a need for that??
Typically, message contracts are only ever used when you need to tightly control the layout of your SOAP message, e.g. to satisfy a legacy system you need to call which requires specific headers and such.
A "normal" WCF call should hardly ever need to use a message contract.
You define your service calls (the methods on your service) using [ServiceContract], and the data structures being passed around as [DataContract]. If you have a DataContract, you have more options as to how to deal with inheritance / polymorphism in your service (more than with the message contract construct).
Marc

Is that possible to change BaseMessage so that it is concrete class with parameterless constructor?
The error message tells that there is no way to initialize the object of type BaseMessage because it is abstract.

The error simply wants you to have a default empty contructor that it can use. However, I agree with marc_s; in the projects I've worked on I've rarely used message contract, the only case I can remember was as part of a file transfer service where file chunks were passed in messasges.

Try decorating your [ServiceContract] with the KnownType attribute. Since TestMessage is not 'visible' from a public operation, this helps the plumbing know how to treat it when it sees it.
If this should allow the [DataContract] to be serialized as a TestMessage your still likely to need to handle multiple messages differently via 'is a' or some other casting.

Well I had declared this default (parameterless) constructor for sure, but that was not still working fine for me, for me the issue was, the access modifier was protected while it should be public:
public constructor() { }
^^^^

Related

Why does ByteBuddy route method delegation to the "wrong" method in this scenario?

I am putting together a very simple ByteBuddy delegate/proxy class.
The intention is (again, very simple) to proxy a class such that any of its non-final, non-private, non-static methods and so forth get routed to equivalent methods on its proxiedInstance field as returned by its getProxiedInstance method. (There should be exceptions made for the usual suspects: equals, hashCode, wait and notify and so on.)
I've set up my proxy class using the subclass strategy. I've also defined two methods, getProxiedInstance and setProxiedInstance, along with a private field named proxiedInstance of the proper type. I've done this using the FieldAccessor.ofBeanProperty() strategy. I've omitted that here for brevity and clarity. The class does in fact contain this field and these two methods.
Then I've defined the method interception like this, statically importing the relevant ElementMatchers methods:
builder
.method(not(isFinal()).and(not(isStatic())).and(not(isPrivate()))
.and((isPublic().and(named("toString")).and(takesArguments(0)).and(returns(String.class)))
.or((not(isDeclaredBy(Object.class)).and(not(named("getProxiedInstance"))).and(not(named("setProxiedInstance"))))))
)
.intercept(MethodDelegation.toMethodReturnOf("getProxiedInstance"));
In English: not final, not static, not private, and either the public String toString() method inherited from Object (or overridden), or any other method not declared by Object.class and not named getProxiedInstance or setProxiedInstance.
Suppose I have a class like this:
public class Frob {
public String sayHello() {
return "Hello!";
}
}
When I create a proxy class for it, instantiate it, and then call toString() on the proxy, I get Hello!.
This suggests to me somehow that the recipe I've quoted above is somehow routing toString() to sayHello().
From reading the MethodDelegation javadocs, it seems that maybe sayHello on the target/delegate object is picked for delegation because it is more specific than the method invoked on the proxy (toString). I guess name matching is lower priority than that.
I think this use case I have is relatively simple. How do I best accomplish it?
The best I could do, which works, but seems perhaps a little clunky or verbose, was this:
builder = builder
.method(not(isDeclaredBy(Object.class))
.and(not(isFinal()))
.and(not(isStatic()))
.and(not(isPrivate()))
.and(not(named("getProxiedInstance")))
.and(not(named("setProxiedInstance"))))
.intercept(MethodDelegation.toMethodReturnOf("getProxiedInstance"))
.method(is(toStringMethod))
.intercept(invoke(toStringMethod).onMethodCall(invoke(named("getProxiedInstance"))));
(toStringMethod is the Method resulting from Object.class.getMethod("toString").)
I think using MethodCall is a better approach to this. MethodDelegation is meant for "catch all proxies" where you inject corresponding dispatchers into what is often a single delegate method, maybe two. Method call is also much more performance since it does not need to do the analysis but just reroutes to a method of a compatible type.

Location of attributes in WCF code? Interface or Code

While looking at a variety of examples and how-tos for creating WCF services I notice that some people decorate the interface code with attributes and others decorate the implmentation code. I understand decorating the interface with [ServiceContract] but where is the proper place for things like [WebGet] or [WebInvoke] or [AspNetCompatibilityRequirements]?
Most attributes' proper location is not up the developer, but specified by the WCF documentation. See the examples in these pages for proper attribute usage.
WebGet - interface, operation contract:
http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webgetattribute.aspx
WebInvoke - interface, operation contract:
http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webinvokeattribute.aspx
AspNetCompatibilityRequirements - service implementation:
http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.aspnetcompatibilityrequirementsattribute.aspx
Since you are coding the class definition, it's best to place them in the same file as the class implementing them. Putting them on the interface makes it hard to remember how the method is to be used. With it right on the class and method implementations, you can't forget!

Adding protobuff-net serialization to WCF through code with knowntypes

I currently have all of my WCF connections defined in code and I'm trying to shoehorn protobuff-net serialization in with little success. None of my contracts are marked with the knowntype attribute as we have a base message with a payload (it would be dozens of knowntypes). We figure out the knowntypes we have and cache them in a class derived from DataContractSerializerOperationBehavior. Then in the overridden CreateSerializer function I pass the cached known types into the DataContractSerializer as follows
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
new DataContractSerializer(type, name, ns, m_Known ?? knownTypes, 0x7FFF, ...)
}
Is there some way to pass a list of known types to the protobuf-net serializer. I realize protobuf-net isn't meant to mirror the serializers for WCF, but it would be nice if they followed the pattern for allowing overriding the knowntypes list. Thanks for any help.
However I don't have the option to treat the Protobuf-net serializer this way (I looked at the ProtoOperationBehavior). Is there anyway to not have known types specified in the
In "v2", the available subtypes can be defined (against a RuntimeTypeModel) on the fly at runtime via .AddSubType(...) (in fact, all the attributes now only serve as a default configuration for the type-model, which can be configured any which way).
However, I should stress that v2 is currently in beta, and as noted in the blog the WCF hooks are currently not included in the beta, purely while I finish validation etc. However, I expect that with your setup as shown in the question it should be trivial (it will merely be a case of passing the model into the XmlObjectSerializer implementation provided).

WCF: SOAP Fault or normal Exception(s) in DataContract class

The main parameter to my Service's OperationContract is a class called Preapproval. In the Preapproval class, there are a few public getters/setters for the DataMember attributes. I have code that validates the input to the setters, such that I would throw an ArgumentException, if say, a parameter is blank or out of the proper bounds for the domain.
If the inputs are invalid, I usually would throw an ArgumentException here. Since this is a WCF situation, must I throw a pre-defined FaultException here rather than ArgumentException? I understand that, elsewhere, I may catch general exceptions and rethrow them as FaultExceptions, but this activity will occur higher up the stack, in some work performed automatically by WCF plumbing.
For example, when a caller invokes my service, the serializer will deserialize their SOAP, attempt to call the setters on my object, and experience the throwing of the ArgumentException, way before my operation is actually invoked. Thus, is it good design practice, in DataContract classes, to simply throw FaultExceptions right away? I really don't want to wire a custom handler up to the channel dispatcher.
I understand that I could simply throw FaultExceptions directly, but I would really like to confine that sort of thing to the service. If it cannot be avoided, I can do it in the supporting classes as well, but I would prefer to write typical code as much as possible, that is not so tightly coupled to System.ServiceModel, etc.
Thanks!
I would leave the FaultExceptions out of your DataContract class -- you might want to use those classes outside of a WCF context.
One approach that would prevent WCF specific code from sneaking into your DataContracts (besides attributes) would be to have the DataContract class throw exceptions and in the service layer use Enterprise Library's WCF Exception Shielding to map those exceptions to fault contracts.
Basically Enterprise Library implements IErrorHandler and converts Exceptions to FaultExceptions. I think a handler is the only way to achieve what you want (since the exceptions are not thrown in your service). The good news is that you really don't have to do much to get it working.
Just add an attribute to your service:
[ServiceContract]
[ExceptionShielding]
public interface IApproval
{
[OperationContract]
[FaultContract(typeof(ApplicationServiceFault))]
[FaultContract(typeof(SystemServiceFault))]
void PreApprove(Preapproval preapproval);
}
and then add some configuration (configuration omitted to save space) to map Exceptions to a FaultContract. Note that your operations will still have to declare FaultContracts.
Your PreApproval class should not be aware that it's being used in a web service. Let it throw whatever exception it would have thrown if it were being called from any other type of application.
The "top level" of your service should catch exceptions and translate them to the appropriate FaultException.

Mocking a Wcf ServiceContract

I want to mock a ServiceContract. The problem is that Moq (and Castle Dynamic-Proxy) copies the attributes from the interface to the dynamic proxy which Wcf don't like. Wcf says: The ServiceContractAttribute should only be define on either the interface or the implementation, not both.
Exception is: InvalidOperationException - The service class of type Castle.Proxies.IWorkOrderRequestServiceProxy both defines a ServiceContract and inherits a ServiceContract from type IWorkOrderRequestService. Contract inheritance can only be used among interface types. If a class is marked with ServiceContractAttribute, it must be the only type in the hierarchy with ServiceContractAttribute. Consider moving the ServiceContractAttribute on type IWorkOrderRequestService to a separate interface that type IWorkOrderRequestService implements
Just experienced the same problem - so +1 for a solution! :-)
Update: http://code.google.com/p/moq/source/browse/trunk/Source/Proxy/CastleProxyFactory.cs contains a reference to a property (collection) called AttributesToAvoidReplicating, looks like a place to start looking in the Moq source code.
Update #2: Nailed it!
Add:
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(ServiceContractAttribute));
before you wire up anything in your kernel.