4

I want a loosely typed parameter in my web method.

I have a scenario where the client can send any of 25 DataContract objects into the WCF operation e.g.

proxy1.myFunction(PersonObject)
proxy1.myFunction(ComputerObject)

My restriction is there should be only one Operation Contract exposed to the client.

How can I design a web method which can take any of the 25 DataContract classes as a parameter? I tried with object as type of parameter and gave KnownType attribute to the DataContract classes but I had no luck during the serialization process.

Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169
user1312242
  • 339
  • 1
  • 3
  • 16

2 Answers2

8

I have just done this, I found you need to add the KnownTypesAttribute to the interface.

[ServiceContract]
[ServiceKnownType(typeof(MyContract1)]
[ServiceKnownType(typeof(MyContract2)]
[ServiceKnownType(typeof(MyContract3)]
public interface IMyService
{
    [OperationContract]
    object TakeMessage();

    [OperationContract]
    void AddMessage(object contract);

}

in you implementation, you will need to check the type to ensure it is one of your DataContracts.

EDIT

If you have a lot of contracts, you can use reflection to add them to the KnownTypes.

internal static class KnownTypeHelper
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider = null)
    {
        var types = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.Namespace == "Company.Path.To.DataContractsNamespace").ToArray();

        return types;
    }
}

Then you can declare your interface as,

[ServiceContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypeHelper))]
public interface IMyService
{
    [OperationContract]
    object TakeMessage( );

    [OperationContract]
    void AddMessage(object contract);
}

This is a much cleaner way of doing it.

TheRealTy
  • 2,409
  • 3
  • 22
  • 32
1

Well one thing that you could try is, create an interface like IObj, and implement this interface for the 25 different data contract objects. Then for your operation contract, let the parameter type be IObj. This would help you out in sending in the 25 params.

Krishna
  • 636
  • 3
  • 8
  • ohh This is a greate idea.. Let me impliment the same.. But I have a question i.e. say Interface IObj has two operations, then all the datacontract classes should implement those. Again another concern is that: say the webmethod took IObj as parameter type... Now, when WCF client sends ComputerObject in that webmethod then after typecasting at WCF Side we can get an Object which is of type IObj.. I mean we might miss out few properties which are not there in IObj.. Please correct me if I am wrong... Anyways letme try this... Thanks a lot for the help :-) – user1312242 Apr 12 '12 at 09:05
  • In the WCF Operation Contract, what you should be doing is check and cast the object for every type. In this way you get ComputerObject and not IObj. But yes, for 25 different types that check could be an additional overhead. – Krishna Apr 12 '12 at 10:01