none
Accept Derived classes in service method RRS feed

  • Question

  • All:

    I have a service that has 4 main methods, Create, Update, Void and Execute.  I tried to model it after the MSCRM OrganizationService. The idea being that you could have any of X number of Messages that inherit from a base class, and you can pass any of the derived classes to the Execute method. So for instance, the Execute method accepts a parameter of type BusinessRequest. Any derivative of BusinessRequest should be able to be passed into Execute. Inside of Execute, I determine what the type was and process it accordingly. The various requests are held in a different assembly but my idea was to be able to add different types of requests/responses and version accordingly, thereby keeping the original signature for the service in place.  

    The Requests and Responses all inherit from a base class which has some very basic properties in it.  It's defined as a DataContract with each of the members being marked as DataMember respectively. The same as the derivatives.  When generated, teh WSDL only shows the primary operations (as expected) but none of the derived classes show up.  So the consumer can't use a service reference to build a proxy that contains each of the possible types. I've decorated the base class with DataContract/DataMember as I mentioned, and then used the KnownType attribute on the base class as well as the derived types. But no matter what I've done so far, I can't get the derived classes to show up in the wsdl so anyone consuming it can't see any of those types short of giving them the assembly itself that contains them.  I know it's possible as MSCRM does it - you can pass a zillion different xxxRequest objects into the Execute method and then cast the response as xxxResponse.  If you use the 'early bound' (it's not true early binding but that's the nomenclature used by Microsoft) approach, each of the different derivatives appears in the proxy class. 

    I used Reflector and JustDecompile to look at how it was built just to sanity check what I've done and I can't see a difference.  I could gladly post a code sample but anything would be pretty verbose. I have a strong feeling I'm just overlooking something simple. But in short, what i"m asking is this - if you are using the Request/Response pattern in a WCF service, and you have a method that accepts any derived type (where the derived types are contained in a statically linked assembly), how do you get them to show up in the wsdl?  CRM obviously has some mechanism of dynamically generating the wsdl b/c each time you create a new entity, it shows up when you update the proxy.  Has anyone run across this problem before? Is it a case of having to just manually generate the wsdl or do something along those lines as no OOB solution exists? I'm guessing that I'm just overlooking something simple, but after fighting it for a few days, I remained stumped.  I've been very careful and done as much Binging as I can so as far as making sure the services are built correctly, the objects themselves are decorated accordingly with DataContract/DataMember/EnumMember - KnownType where applicable, I'm sure I've hit that all correctly. I'm either missing something simple or I'm way off base. Any suggestions would be greatly appreciated.


    Cordially, W.G.Ryan - www.dynamics4.com

    Saturday, July 5, 2014 4:44 AM

Answers

  • Hi,

      >> I have a service that has 4 main methods, Create, Update, Void and Execute. 

      >> and you can pass any of the derived classes to the Execute method.

    It looks like you implemented some functions like this in your WCF service:

    [OperationContract]
    string Execute(BaseClass baseclass);

    and the BaseClass class have several derived classes which you wanna pass them as parameters when you call the Execute method via service client, however, you could not use/see the derived classes objects from service client due to wsdl did not include them.

    If my understanding of your issue is correct, I'd like to suggest you to add ServiceKnownType attribute  to your IService to specify those derived class type to include.

    You can try something like:

     [ServiceContract]
        [ServiceKnownType(typeof(DerivedClassOne))]
        [ServiceKnownType(typeof(DerivedClassTwo))]
        public interface IService1
        {

            [OperationContract]
            string Execute(BaseClass baseclass);
            // TODO: Add your service operations here
        }

    Then you could use/see the DerivedClassOne and DerivedClassTwo classes in service client. You may also wanna refer to http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute(v=vs.110).aspx for more information about ServiceKnownTypeAttribute.

       >> and then used the KnownType attribute on the base class as well as the derived types.

    In addition, the Data Contract Known Types is a different topic at: http://msdn.microsoft.com/en-us/library/ms730167(v=vs.110).aspx

    Best Regards,

    Ming Xu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Monday, July 7, 2014 8:41 AM

All replies

  • Hi,

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

    Best Regards,
    Amy Peng

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, July 7, 2014 6:50 AM
    Moderator
  • Hi,

      >> I have a service that has 4 main methods, Create, Update, Void and Execute. 

      >> and you can pass any of the derived classes to the Execute method.

    It looks like you implemented some functions like this in your WCF service:

    [OperationContract]
    string Execute(BaseClass baseclass);

    and the BaseClass class have several derived classes which you wanna pass them as parameters when you call the Execute method via service client, however, you could not use/see the derived classes objects from service client due to wsdl did not include them.

    If my understanding of your issue is correct, I'd like to suggest you to add ServiceKnownType attribute  to your IService to specify those derived class type to include.

    You can try something like:

     [ServiceContract]
        [ServiceKnownType(typeof(DerivedClassOne))]
        [ServiceKnownType(typeof(DerivedClassTwo))]
        public interface IService1
        {

            [OperationContract]
            string Execute(BaseClass baseclass);
            // TODO: Add your service operations here
        }

    Then you could use/see the DerivedClassOne and DerivedClassTwo classes in service client. You may also wanna refer to http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute(v=vs.110).aspx for more information about ServiceKnownTypeAttribute.

       >> and then used the KnownType attribute on the base class as well as the derived types.

    In addition, the Data Contract Known Types is a different topic at: http://msdn.microsoft.com/en-us/library/ms730167(v=vs.110).aspx

    Best Regards,

    Ming Xu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Monday, July 7, 2014 8:41 AM