Search code examples
c#wcfbehaviorwcf-behaviouriservicebehaviors

Modify returnvalue in WCF operation


I want to ensure that all our operations that return datasets in our WCF has .ExcludedSchema value set in Property SchemaSerializationMode.

Can I do this with a CustomBehavior? I tried to implement a CustomDispatchBehavior and add a MessageInspector, but the methods AfterReceiveRequest and BeforeSendReply doesn't let me do anything with the return value. In BeforeSendreply, the return value has already been serialized. Where can I plug in my code?

    public class CustomDispatchBehavior : BehaviorExtensionElement, IServiceBehavior
    {

        public override Type BehaviorType
        {
            get { return typeof(CustomDispatchBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new CustomDispatchBehavior();
        }

        void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
            //throw new NotImplementedException();
        }

        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            //throw new NotImplementedException();
            foreach (ChannelDispatcher chanDisp in serviceHostBase.ChannelDispatchers)
            {
                foreach (EndpointDispatcher ed in chanDisp.Endpoints)
                {
                    ed.DispatchRuntime.MessageInspectors.Add(new MyMessageInspector());

                }
            }
        }

        void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            //throw new NotImplementedException();
        }

    }

Solution

  • I solved it using the IParametorInspector

        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {      
    
            foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers)
            {
                foreach (EndpointDispatcher epDisp in chDisp.Endpoints)
                {                   
                    foreach (DispatchOperation op in epDisp.DispatchRuntime.Operations)
                        op.ParameterInspectors.Add(new DataSetParameterInspector());
                }
            }
    
        }
    

    and the inspector looks like this

    public class DataSetParameterInspector : IParameterInspector
    {
    
        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            Type t =returnValue.GetType();
            if (t.IsSubclassOf(typeof(GlobalUtils.RR.Response)))
            {
                foreach (var pi in t.GetProperties())
                {
                    if (pi.PropertyType.IsSubclassOf(typeof(System.Data.DataSet)))
                    {
                        object parameter = pi.GetValue(returnValue, null);
                        if (parameter != null)
                            ((System.Data.DataSet)parameter).SchemaSerializationMode = System.Data.SchemaSerializationMode.ExcludeSchema;
                    }
                }
            }
        }