由于最近工作一直在做wcf平台上的开发,所以决定先结合自己平时工作中的经验实践写一个WCF的系列,希望能对大家有所帮助。

首先,说到WCF,就不得不提Endpoint这个概念,而Endpoint则由ABC组成,Adress,Binding和Contract。对于这些基础的知识,我向大家推荐Artech写的一个系列,大家可以去读一下,我觉得写得非常好,读罢获益匪浅。

http://www.cnblogs.com/artech/archive/2007/02/28/659331.html

接着来说ABC的问题。在Binding里面我们只能指定编码方式而不能指定序列化的方式,序列化的方式只能在程序里面指定。而最近我们的team遇到了这样一个需求,大致要求如下:

1.       我们team当前研发的web service是restful的,而我们希望用户能在request里面输入一个”alt=xml”或者”alt=json”来决定返回的数据格式是xml或者json

2.       我们希望动态决定返回数据这个功能是独立的,可插拔的模块,并且可以方便地决定哪些service用这个功能而哪些service不用这个功能

3.       我们希望可以通过配置的方式来插拔这个功能

好了,大致需求就这么多。针对以上需求,我们想到写一个Custom Behavior来实现这些需求。

对于Custom Behavior, 先做一点基本知识的阐述:

我们可以在五个不同的点来定制我们自己的Custom Behavior

ParameterInspection

MessageFormatting

OperationInvoker

MessageInspection

OperationSelector

由于这个需求是需要根据用户输入的参数来动态的决定返回的response的格式,所以我当时选择写一个MessageFormatter的CustomBehavior

然后CustomBehavior分以下几种:

ServiceBehavior

EndpointBehavior

ContractBehavior

OperationBehavior

在WCF里面,有三种方式来添加behavior:

ServiceBehavior

EndpointBehavior

ContractBehavior

OperationBehavior

通过代码方式添加

通过Attribute的方式

通过配置的方式

好了根据以上阐述,由于我们想使用配置来插拔该功能,所以我们选用Endpoint Behavior

然后,我们可以自己实现一个IDispatchMessageFormatter

public class MessageFormatter : IDispatchMessageFormatter
    {
        private const string CONTENT_TYPE_XML = "text/xml";
        private const string CONTENT_TYPE_JSON = "application/Json";
        private readonly IDispatchMessageFormatter originalFormatter;

public MessageFormatter(IDispatchMessageFormatter dispatchMessageFormatter)
        {
            this.originalFormatter = dispatchMessageFormatter;
        }

#region IDispatchMessageFormatter
        public void DeserializeRequest(Message message, object[] parameters)
        {
            this.originalFormatter.DeserializeRequest(message,parameters);
        }

public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
        {
        }

#endregion
    }

我们需要实现反序列化和序列化的2个方法。

而根据现有的需求,我们可以用WCF中默认的DataContract序列化,因为DataContract序列化既可以序列化出xml也可以序列化出Json,所以我们只需要给Model打上DataContract标签和DataMember标签即可。

我们可以在SerializeReply方法中做如下操作

string alt = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["alt"];
if(alt=="xml")
{
   WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Xml;
   WebOperationContext.Current.OutgoingResponse.ContentType = CONTENT_TYPE_XML;
}

if(alt=="json")
{
   WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;
   WebOperationContext.Current.OutgoingResponse.ContentType = CONTENT_TYPE_JSON;
}

然后,我们需要把这个MessageFormatter加到一个EndpointBehavior里面去。

我们可以实现一个Endpoint Behavior

public class MessageFormatterEndpointBehavior : IEndpointBehavior
    {
        #region IEndpointBehavior Members
        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            foreach (OperationDescription operation in endpoint.Contract.Operations)
            {
                operation.Formatter = new MessageFormatter(operation.Formatter);
            }
        }

public void Validate(ServiceEndpoint endpoint)
        {
        }
        #endregion
    }

接下来,由于Endpoint Behavior是不能直接写进配置文件中的,为了实现可配置,我们需要为我们的Endpoint Behavior写一个Extension Element.

public class MessageFormatterEndpointBehaviorExtensionElement : BehaviorExtensionElement
    {
        public override Type BehaviorType
        {
            get { return typeof(MessageFormatterEndpointBehavior); }
        }

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

然后,再把这个extension element配置到文件中。

<system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webBinding">
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="WCFMessageFormatter.Services.TankService" behaviorConfiguration="testServiceBehavior">
        <endpoint address="http://localhost:8080/TankService" behaviorConfiguration="webBehavior"
                  binding="webHttpBinding" bindingConfiguration="webBinding" contract="WCFMessageFormatter.Contracts.ServiceContracts.ITankService">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp />
          <endpointMessageFormatter />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="testServiceBehavior">
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add
          name="endpointMessageFormatter"
          type="WCFMessageFormatter.CustomServiceBehaviors.MessageFormatterEndpointBehaviorExtensionElement, WCFMessageFormatter.CustomServiceBehaviors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
          />
      </behaviorExtensions>
    </extensions>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule,System.Web.Routing,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35" />
    </modules>
  </system.webServer>
</configuration>

好了,这样一来就可以实现我们需求中提到的功能了。

在下一节中,我将继续这个例子来说说WCF Custom Behavior和序列化的相关内容,下一篇中将提到几个需求变化以及我们如何应对这些变化。

在这个例子写完时我将附上完整的项目代码。

另外,最近也有一些朋友通过博客园上的联系方式与我联系,时间关系,我并不能对所有问题都做出回答,十分抱歉,大家有任何问题还是可以给我留言,或者邮件,QQ联系,我会尽量回复。

转载于:https://www.cnblogs.com/FlyEdward/archive/2012/06/25/WCF_CustomBehavior.html

WCF系列(1)—— CustomBehavior 入门相关推荐

  1. 「译」JUnit 5 系列:基础入门

    2019独角兽企业重金招聘Python工程师标准>>> 原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, ...

  2. 3月24日下午专家聊天室:轻松掌握WCF 帮你找到入门砖

    各位网友,大家注意了,WCF聊天活动将要在下周一在51CTO举行,感兴趣的网友请积极关注和参与,奖品丰厚,10本精彩iT专业图书等你拿!获奖率很高哦!   聊天室入口>>>   获奖 ...

  3. SpringBoot系列: RestTemplate 快速入门

    ==================================== 相关的文章 ==================================== SpringBoot系列: 与Sprin ...

  4. matlab如何测两点的角度_【邢不行|量化小讲堂系列01-Python量化入门】如何快速上手使用Python进行金融数据分析...

    引言: 邢不行的系列帖子"量化小讲堂",通过实际案例教初学者使用python进行量化投资,了解行业研究方向,希望能对大家有帮助. [历史文章汇总]请点击此处 [必读文章]: [邢不 ...

  5. WCF系列(一)BasicHttpBinding 和 WsHttpBinding 的不同点

    aaaaaaaaaaaaaaaaaa WCF系列(一)[翻译]BasicHttpBinding 和 WsHttpBinding 的不同点 2010-02-21 12:23 by Virus-Beaut ...

  6. python中shift函数rolling_【邢不行|量化小讲堂系列18-Python量化入门】简易波动指标(EMV)策略实证...

    引言: 邢不行的系列帖子"量化小讲堂",通过实际案例教初学者使用python进行量化投资,了解行业研究方向,希望能对大家有帮助. 个人微信:xingbuxing0807,有问题欢迎 ...

  7. 反射学习系列1-反射入门

    反射学习系列目录 反射学习系列1-反射入门 反射学习系列2-特性(Attribute) 反射学习系列3-反射实例应用 作者 Reflection,中文翻译为反射.这是.Net中获取运行时类型信息的方式 ...

  8. AutoSAR系列讲解(入门篇)5.2-描述文件

    AutoSAR系列讲解(入门篇)5.2-描述文件 描述文件 一.主要流程 二.各描述文件介绍 1.SWC描述文件 2.系统约束描述文件 3.ECU资源描述文件 4.系统配置描述文件 5.ECU提取文件 ...

  9. AutoSAR系列讲解(入门篇)4.1-BSW概述

    AutoSAR系列讲解(入门篇)4.1-BSW概述 BSW概述 一.什么是BSW 二.BSW的结构 1.微控制器硬件抽象层(MCAL) 2.ECU抽象层 3.服务层 四.复杂驱动 三.再将结构细分 B ...

  10. AutoSAR系列讲解(入门篇)5.1-方法论概述

    AutoSAR系列讲解(入门篇)5.1-方法论概述 方法论概述 一.一些必要的概念 1.供应链上的称呼 2.什么是方法论 二.工作流程 1.普通流程 2.AutoSAR标准流程 方法论概述 -> ...

最新文章

  1. redis主从复制搭建
  2. Junit 3 与 Junit 4写法
  3. 理解js中this的指向
  4. 送给 Java 程序员的 Spring 学习指南
  5. 【TensorFlow】tf.nn.softmax_cross_entropy_with_logits中的“logits”到底是个什么意思?
  6. 使命召唤手游新的狙击枪,升级之后堪比巴雷特?会玩的就是
  7. 《程序员面试宝典》精华 面向对象部分
  8. 折叠屏手机又要延期?华为:Mate X按原计划开售
  9. 计算机毕业论文java毕业设计论文题目基于SpringBoot项目源码旅游信息管理系统[包运行成功]
  10. 汽车维修企业管理【1】
  11. U盘有必要安全弹出吗??
  12. android fresco的底层,Fresco源码分析之DraweeView
  13. 华为鸿蒙福田办公室,华为鸿蒙第一批名单
  14. Regionals 2014 Asia - Daejeon
  15. latex出现File ended while scanning use of \frame.错误
  16. ERROR Plumber found unhandled error: Error in plugin gulp-htmlmin
  17. iphone 4s越狱
  18. error C3203
  19. P30鸿蒙ota升级,强悍!华为P30Pro连接硬盘,传1G、2G视频原来可以这么快
  20. linux添加xfs磁盘,centos7 LV XFS添加磁盘

热门文章

  1. 2017 ICPC西安区域赛 A - XOR ,线段树合并线性基
  2. python 面向对象 新式类和经典类
  3. 完成聊天室的私聊功能
  4. 一个简单的时间轴demo
  5. Spring学习9-MyEclipse中Spring工程使用@Resource注释的问题
  6. [开发技巧3]不显示报表直接打印
  7. 7怎样设置禁网_怎样才能提升网站内页的收录?
  8. easyui启用行号错位解决方案
  9. 华强北三代悦虎1562A怎么样?
  10. 小程序 地图 开发 组件 覆盖物