WCF interface and derived class - wcf

I have a WCF service and have to expose an interface as datacontract. There are two derived classes from the interface.
The WCF service will return an object of the derived type.The client will have to cast it as a derived class. Is that possible on the client side ?.What should be my approach.

If you have derived classes, you need to "advertise" those on the data contract:
[DataContract]
[KnownType(typeof(DerivedType1))]
[KnownType(typeof(DerivedType2))]
public class BaseType
{
......
}
or you can also specify these kind of relations on a service contract:
[ServiceKnownType(typeof(DerivedType1))]
[ServiceKnownType(typeof(DerivedType2))]
[ServiceContract()]
public interface IService
{
[OperationContract]
BaseType GetItems();
}
Check out the MSDN docs on Data Contract Known Types or Service Known Types for more background info.

Related

WCF generic property is not mapped in derived class

I have:
[DataContract]
public class A
{
[DataMember]
public int X { get; set; }
}
[DataContract]
[KnownType(typeof(Derived<A>))]
public class Base {}
[DataContract]
public class Derived<T>: Base {
[DataMember]
public T Data {get; set; }
}
Service method returns IEnumerable of Base class containing object of Derived class.
Auto-generated WCF client retrieves data and correctly detects type and creates instances of the Derived class, but Derived.Data.X is not mapped, i.e. has 0. The soap message received is correct.
Any ideas why the generic property of the derived class is not correctly mapped from the soap message in the client?
I strongly recommend you to avoid generics in service contracts. SOA world is not friendly with generic type in the service contract. Please look problems reported by others:
Error when updating service reference.The URI prefix is not recognized
WCF. Service generic methods
WCF generic property is not mapped in derived class
http://social.msdn.microsoft.com/Forums/vstudio/en-US/2a9a2fc6-9e01-4112-8948-4192c516c6e7/how-to-use-generics-in-wcf-service

Cannot Serialize interface

This is my ABC on the server side:
<endpoint address="msmq.formatname:DIRECT=OS:.\private$\imhmsgs"
binding="msmqIntegrationBinding"
bindingConfiguration="IncomingMessageHandlerBinding"
contract="TMC.Services.Contracts.Messages.IInboundMessageHandlerService">
As soon as I do an .Open() to host the service, I get the exception:
Cannot serialize interface
XYZ.Services.Contracts.Messages.Interfaces.IMyMessage.
My IMyMessage interface:
[ServiceContract]
[ServiceKnownType(typeof(IMyMessage))]
[ServiceKnownType(typeof(ConcreteMessage))]
public interface IInboundMessageHandlerService
{
[OperationContract(IsOneWay = true, Action = "*")]
void ProcessIncomingMessage(MsmqMessage<IMyMessage> incomingMessage);
}
The implementor for that interface:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
ReleaseServiceInstanceOnTransactionComplete = false)]
public class InboundMessageHandlerService : IInboundMessageHandlerService
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void ProcessIncomingMessage(MsmqMessage<IMyMessage> incomingMessage)
{
}
}
The type that is being created by the client basically is a concrete class, which derives from a base class and also an interface (IMyMessage) and then places this on the MSMQ.
After some testing, if I remove the service known type attributes and just instead use say "string" instead, then it seems to open the host but faults (because the message type is not what it was expecting).
where am I going wrong?
On further testing I see that if I only specify the concrete type, it works.
This is not quite what I was expecting.
how am I able to create it so that the service can take a known interface and classes which that interface has? The idea is for the client (using the same contract and classes) to send the message as "IMyMessage" and for the WCF service to pick that up as "IMyMessage" and go ahead and find out the type of message/object it is.
How?
Your contract is an interface, but the definition within the contract must be concrete classes.
In your case it looks like you want to send over a list of things, those things could be different but they all support the same interface.
The problem is that when WCF deserialises what has been sent over the wire, it needs to deserialise it the a concrete type. If it just has an interface in the definition and 20 different types that implement that definition, it does not know what to do with it.
What you can do is have a base type that implements the interface, all your classes inherit from the base type and you use the base type in your contact.

Extension methods in a data contract

Can we two WCF services where one service contract derives from another and have an extension method inside the derived contract. what will be the result of accessing this contract from the WCF Client. I.e. what will happen if IDServiceis accessed
E.g.
[ServiceContract]
public interface IBaseService
{
public void A();
...
}
[ServiceContract]
public interface IDService: IBaseService
{
public static void B(this IBaseService S);
....
}
You can't define static methods in an interface (nor the access modifier public which you've specified above either).
A good question - got me to a lot of head scratching.
Extension method is meaningless to WCF - and WSDL for that matter.
If you use Service Reference to generated the client, you would not see the extension method (since WSDL would not know anything about the extension method) so you cannot use it.
If you use DLL/Project reference, your code will be called locally and not through the proxy.

WCF with shared objects and derived classes on client

I have a WCF service and I'm sharing types with a client in a shared assembly.
If the client create a derived class will it be possible to pass back the derived type to the service so that I can read the added properties through reflection ?
I tried but having issues with KnownTypes since the service don't know how to deserialize the derived type.
[Serializable]
public abstract class Car : ICar
{........
//on the client :
[Serializable]
public class MyCar : Car
{......
when passing myCar to Service I get the exception complaining about knownType but I cant add this on the server since I wont know what the client will be sending through and I want to handle extra properties through reflection.
Possible to register client types as knowntypes at runtime ?
Is this maybe the solution ?
http://blogs.msdn.com/b/sowmy/archive/2006/03/26/561188.aspx
This is not possible. Both service and client has to know what types will be sent in messages. If you want to use known type you have to define that relation to parent type on the service.
Why do you need to know added properties on the server?
I think there is a way.
I vaguely remember that when I studied WCF, I met ExtensionData which should be a mechanism to get everything that does not match the serialization of the class. for example, if you enable ExtensionData and you are in this situation
//Server
public class GenericRQ
{
public string GenericProperty {get;set;}
}
public Service GenericService
{
Public void GenericMethod(GenericRQ RQ)
{
}
}
// client
Public class MoreSpecificRQ : GenericRQ
{
public string SpecificProperty {get;set;}
}
At
Public void GenericMethod(GenericRQ RQ)
{
// the serializer adds automatically in RQ.ExtensionData everything that has come and that does not match the class GenericRQ.
}
On how to enable ExtensionData you to easily search on the web

WCF Additional Proxy Classes

I have a WCF webservice that has the following service contract
[ServiceContract(Namespace = "http://example.org")]
public interface IEquinoxWebservice
{
[OperationContract]
Guid Init();
[OperationContract]
List<Message> Dequeue(Guid instanceId);
[OperationContract]
void Enqueue(Guid instanceId, Message message);
[OperationContract]
void Dispose(string instanceId);
}
Message class is an abstract class that is implemented by a bunch of concrete message classes.
I want to make all the concrete message classes available in the client proxy that is generated. Not just the message class.
Is there any way to make them available as types in the webservice so the standard Visual Studio proxy generator will create them?
You need to specify those types. See Data Contract Known Types.