How to use IDispatchMessageInspector in a WCF Service?

前端 未结 5 1722
面向向阳花
面向向阳花 2020-12-10 13:24

I am trying to use IDispatchMessageInspector in a WCF service implementation to access custom header values.

Something like:

public class MyService :         


        
5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-10 14:00

    I'm using IClientMessageInspector for same goal. Here is how you can apply them from code:

     var serviceClient = new ServiceClientClass(binding, endpointAddress);
    serviceClient.Endpoint.Behaviors.Add(
                new MessageInspectorEndpointBehavior());
    
    
    /// 
    /// Represents a run-time behavior extension for a client endpoint.
    /// 
    public class MessageInspectorEndpointBehavior : IEndpointBehavior
        where T: IClientMessageInspector, new()
    {
        /// 
        /// Implements a modification or extension of the client across an endpoint.
        /// 
        /// The endpoint that is to be customized.
        /// The client runtime to be customized.
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new T());
        }
    
        /// 
        /// Implement to pass data at runtime to bindings to support custom behavior.
        /// 
        /// The endpoint to modify.
        /// The objects that binding elements require to support the behavior.
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            // Nothing special here
        }
    
        /// 
        /// Implements a modification or extension of the service across an endpoint.
        /// 
        /// The endpoint that exposes the contract.
        /// The endpoint dispatcher to be modified or extended.
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            // Nothing special here
        }
    
        /// 
        /// Implement to confirm that the endpoint meets some intended criteria.
        /// 
        /// The endpoint to validate.
        public void Validate(ServiceEndpoint endpoint)
        {
            // Nothing special here
        }
    }
    

    And here is sample implementation of MessageInspector I'm using to pass client version to server, and retrieve server version in custom headers:

    /// 
    /// Represents a message inspector object that can be added to the MessageInspectors collection to view or modify messages.
    /// 
    public class VersionCheckMessageInspector : IClientMessageInspector
    {
        /// 
        /// Enables inspection or modification of a message before a request message is sent to a service.
        /// 
        /// The message to be sent to the service.
        /// The WCF client object channel.
        /// 
        /// The object that is returned as the  argument of
        /// the  method.
        /// This is null if no correlation state is used.The best practice is to make this a  to ensure that no two
        ///  objects are the same.
        /// 
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            request.Headers.Add(new VersionMessageHeader());
            return null;
        }
    
        /// 
        /// Enables inspection or modification of a message after a reply message is received but prior to passing it back to the client application.
        /// 
        /// The message to be transformed into types and handed back to the client application.
        /// Correlation state data.
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            var serverVersion = string.Empty;
            var idx = reply.Headers.FindHeader(VersionMessageHeader.HeaderName, VersionMessageHeader.HeaderNamespace);
            if (idx >= 0)
            {
                var versionReader = reply.Headers.GetReaderAtHeader(idx);
                while (versionReader.Name != "ServerVersion"
                       && versionReader.Read())
                {
                    serverVersion = versionReader.ReadInnerXml();
                    break;
                }
            }
    
            ValidateServerVersion(serverVersion);
        }
    
        private static void ValidateServerVersion(string serverVersion)
        {
            // TODO...
        }
    }
    
    public class VersionMessageHeader : MessageHeader
    {
        public const string HeaderName = "VersionSoapHeader";
        public const string HeaderNamespace = "";
        private const string VersionElementName = "ClientVersion";
    
        public override string Name
        {
            get { return HeaderName; }
        }
    
        public override string Namespace
        {
            get { return HeaderNamespace; }
        }
    
        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteElementString(
                VersionElementName,
                Assembly.GetExecutingAssembly().GetName().Version.ToString());
        }
    }
    

提交回复
热议问题