跟着Artech学习WCF扩展(4) 扩展MessageInspector

自定义MessageInspector

在client端和service端都有自己的MessageInspector,client端叫做ClientMessageInspector,实现System.ServiceModel.Dispatcher.IClientMessageInspector interface,而service端叫做 DispatchMessageInspector, 实现了System.ServiceModel.Dispatcher.IDispatchMessageInspector interface。DispatchMessageInspector允许你在request message交付到具体的DispatchOperation付诸执行之前或者reply message返回client之前对incoming message/outgoing message进行检验、修改或者其他一些基于message的操作;

IDispatchMessageInspector的定义很简单

1
2
3
4
5
6
public interface IDispatchMessageInspector
{
    // Methods
    object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext);
    void BeforeSendReply(ref Message reply, object correlationState);
}

在实际的项目开发中,MessageInspector使用相当广范,比如:我们可以定义自己的MessageInspector实现Logging功能;或者在Client端通过ClientMessageInspector添加一些与业务无关的context信息,并在service通过DispatchMessageInspector将其取出。在本系列后续的部分我将给你一个application context propagation的具体应用。

剩下的地方在这里:点我

代码下载:点我

Client端对 IClientMessageInspector 进行实现

在service端对IDispatchMessageInspector进行实现

但Artech在service端对 ICallContextInitializer进行了实现

出去学习的目的,拼拼代码 也把IDispatchMessageInspector实现了

不过不知道对不对 忍者  自己拼代码实在是盲人摸像 搞了一天才弄明白,不对是还没弄明白

通过细查 发现这个扩展 实在是太有用了外星人

部分代码如下作为备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
 
namespace Artech.ContextPropagation
{
   public class DispatchMessageInspectorTest:System.ServiceModel.Dispatcher.IDispatchMessageInspector
    {
       public bool IsBidirectional
       { get; set; }
 
       public DispatchMessageInspectorTest()
           : this(false)
       {
 
       }
 
       public DispatchMessageInspectorTest(bool isBidirectional)
       {
           this.IsBidirectional = isBidirectional;
       }
 
 
  
 
 
        //DispatchMessageInspector
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            ApplicationContext context = request.Headers.GetHeader<ApplicationContext>(ApplicationContext.ContextHeaderLocalName, ApplicationContext.ContextHeaderNamespace);
            if (context == null)
            {
                return null;
            }
 
            ApplicationContext.Current = context;
            return ApplicationContext.Current;
        }
 
        public void BeforeSendReply(ref Message reply, object correlationState)
        {
 
            if (!this.IsBidirectional)
            {
                return;
            }
 
            ApplicationContext context = correlationState as ApplicationContext;
            if (context == null)
            {
                return;
            }
            MessageHeader<ApplicationContext> contextHeader = new MessageHeader<ApplicationContext>(context);
            OperationContext.Current.OutgoingMessageHeaders.Add(contextHeader.GetUntypedHeader(ApplicationContext.ContextHeaderLocalName, ApplicationContext.ContextHeaderNamespace));
            ApplicationContext.Current = null;
 
        }
 
 
 
 
    }
}

 

=========

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
 
namespace Artech.ContextPropagation
{
    public class DispatchMessageInspectorTestBehavior : IEndpointBehavior
    {
        public bool IsBidirectional
        { get; set; }
 
 
        public DispatchMessageInspectorTestBehavior()
            : this(false)
        {
 
        }
 
        public DispatchMessageInspectorTestBehavior(bool isBidirectional)
        {
            this.IsBidirectional = isBidirectional;
        }
 
 
        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
           
        }
 
        public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new ContextAttachingMessageInspector(this.IsBidirectional));
        
        }
 
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
 
            DispatchMessageInspectorTest inspector = new DispatchMessageInspectorTest(this.IsBidirectional);
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }
 
        public void Validate(ServiceEndpoint endpoint)
        {
             
        }
    }
}

 

==============

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Configuration;
using System.Configuration;
 
namespace Artech.ContextPropagation
{
   public class DispatchMessageInspectorTestElement:BehaviorExtensionElement
    {
       [ConfigurationProperty("isBidirectional", DefaultValue = false)]
       public bool IsBidirectional
       {
           get
           {
               return (bool)this["isBidirectional"];
           }
           set
           {
               this["isBidirectional"] = value;
           }
       }
 
        public override Type BehaviorType
        {
            get { return typeof(DispatchMessageInspectorTestBehavior); }
        }
 
        protected override object CreateBehavior()
        {
            return new DispatchMessageInspectorTestBehavior(IsBidirectional);
        }
    }
}

 

posted @   互联网Fans  阅读(910)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示