WCF 拦截过滤跟踪Request替代消息Response
参考文章:
http://www.cnblogs.com/mushishi/p/4779826.html (wcf利用IDispatchMessageInspector实现接口监控日志记录和并发限流)
http://www.programgo.com/article/68032711246/ (WCF笔记(6)消息拦截与篡改)
http://www.cnblogs.com/artech/archive/2008/09/01/1280939.html ( 创建一个简单的WCF SOAP Message拦截、转发工具[上篇])
http://www.cnblogs.com/huangxincheng/p/4621971.html (高级玩法之自定义Behavior)
http://www.cnblogs.com/Terrylee/archive/2008/11/17/wcf-messaging-features-core.html (消息处理功能核心)
https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.aspx
http://www.wiktorzychla.com/2015/11/string-trimming-wcf-inspector-for-json.html (String trimming WCF inspector for JSON binding)
InterfaceCallHelper
public class InterfaceCallHelper { /// <summary> /// 获取调用接口名称 /// </summary> public void GetInterfaceName() { //PathInfo : /Get_InfoHotList/MjQ=&MA== string pathInfo = HttpContext.Current.Request.PathInfo; if (string.IsNullOrEmpty(pathInfo)) return; pathInfo = pathInfo.Substring(1); //先截取第一个斜杠 int indexOf = pathInfo.IndexOf("/", StringComparison.Ordinal); InterfaceName = indexOf > 0 ? pathInfo.Substring(0, indexOf) : pathInfo; } /// <summary> /// 判断接口是否可用 /// </summary> /// <returns></returns> public bool GetInterFaceEnabled() { } /// <summary> /// 返回接口不可用 /// </summary> /// <returns></returns> public returnresult ReturnInterFaceDisabled() { var checkDataresult = new returnresult { msg = string.Format("{0}接口,当前状态为不可用", InterfaceName), code = "9999" }; return checkDataresult; }
IDispatchMessageInspector
public class InterfaceInspector : IDispatchMessageInspector { InterfaceCallHelper icHelper = new InterfaceCallHelper(); /// <summary> /// // 此方法的返回值 将作为方法BeforeSendReply的第二个参数 object correlationState传入 /// </summary> /// <param name="request"></param> /// <param name="channel"></param> /// <param name="instanceContext"></param> /// <returns></returns> public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { icHelper.GetInterfaceName(); icHelper.UpdateInterfaceClickCount(); bool isInterFaceDisabled = !icHelper.GetInterFaceEnabled(); if (isInterFaceDisabled) instanceContext.Abort(); return isInterFaceDisabled; } public void BeforeSendReply(ref Message reply, object correlationState) { var isInterFaceDisabled = (bool)correlationState; if (!isInterFaceDisabled) return; dataresult dr = icHelper.ReturnInterFaceDisabled(); string convertedBody = JsonHelper.Serialize(dr); //构造消息 MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(convertedBody)); XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(ms, XmlDictionaryReaderQuotas.Max); Message newMessage = Message.CreateMessage(reader, int.MaxValue, MessageVersion.None); //构造消息属性 var hrmProperty = new HttpResponseMessageProperty(); hrmProperty.Headers.Add(new NameValueCollection { {"Content-Type", "application/json; charset=utf-8"} }); var mp = new MessageProperties { {"WebBodyFormatMessageProperty", new WebBodyFormatMessageProperty(WebContentFormat.Json)}, {"httpResponse", hrmProperty} }; newMessage.Properties.CopyProperties(mp); //替换消息 reply = newMessage; } }
InterfaceInspectorBehaviorAttribute
public class InterfaceInspectorBehaviorAttribute : Attribute, IServiceBehavior { #region implement IServiceBehavior public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) { foreach (ChannelDispatcher channelDispather in serviceHostBase.ChannelDispatchers) { foreach (var endpoint in channelDispather.Endpoints) { // holyshit DispatchRuntime endpoint.DispatchRuntime.MessageInspectors.Add(new InterfaceInspector()); } } } public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) { } #endregion }
ISERVICE
[ServiceContract] public interface ISERVICE { }
MySERVICE
[InterfaceInspectorBehavior] public class MySERVICE : ISERVICE { }