为REST形式的WCF使用newtonsoftJson转换器

原文:http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters.aspx

在编写Rest形式的WCF的时候,如果消息格式设置为Json,则默认是使用DataContractJsonSerializer这个类来做Json转换的;

关于这个类,地球人都知道他做json的时候是非常不友好的,不光是要设一堆的knowtype,而且对于DataTable,居然会返回xml形式,

对于Dictionary,使用冗余形式的{“Key”:"XXX","Value":"YYY"}

而不是大家都喜闻乐见的{“XXX”:“YYY”}这种形式,不光丑,还占地方

可能这种缺点连国外的牛人都看不下去了,所以,就有了原文这篇文章

这个牛人做的是编程方式绑定的自定义behavior,而我原来的WCF是windows 服务形式的,而且用的是config配置,所以为了备忘,特记录以下过程:


  1. 把他上传的代码包下载下来:
  2. 把他代码包中的NewtonsoftJson*.cs和RawBodyWriter.cs下载到自己的项目中(放在同一个文件夹中,命名空间也相同)
  3. 把他的Program.cs中定义的MyRawMapper这个类也放在同样的包中
  4. 把NewtonsoftJsonBehavior.cs中的108~112行注释掉,因为这一行他不允许使用uriTemplate,而我要使用uriTemplate来定制自己的服务uri,否则uri只能和方法名相同:
                //string uriTemplate = this.GetUriTemplate(operation);
                //if (uriTemplate != null)
                //{
                //    throw new InvalidOperationException("UriTemplate support not implemented in this behavior.");
                //}
    如我的服务是这样定义的:
            [WebInvoke(Method="POST",BodyStyle=WebMessageBodyStyle.Bare, UriTemplate = "Sql",RequestFormat=WebMessageFormat.Json,  ResponseFormat = WebMessageFormat.Json)]
            SqlResult GetData(string sql);
    其中UriTemplate = "Sql",表明我的服务Uri是“Sql”而不是“GetData”,这样更具有灵活性
  5. 在同样的包中增加一个类:
        public class NewtonJsonBehaviorExtensionElement : BehaviorExtensionElement
        {
    
            public override Type BehaviorType
            {
                get { return typeof(NewtonsoftJsonBehavior); }
            }
    
            protected override object CreateBehavior()
            {
                return new NewtonsoftJsonBehavior();
            }
        }
  6. 修改配置文件:
    1. 增加行为扩展:
      <extensions>
      
        <behaviorExtensions>
          <add name="newtonsoftJsonBehavior"  type="<命名空间>.NewtonJsonBehaviorExtensionElement,<程序集>"/>
        </behaviorExtensions>
      </extensions>
        </system.serviceModel>
    2. 给此服务绑定的上添加RawMapper:
            <webHttpBinding>
              <binding name="XXX" contentTypeMapper="<命名空间>.JsonRawMapper,<程序集>">

    3. 给此服务绑定的终结点上添加自定的json扩展:
          <endpointBehaviors>
            
              <behavior name="WebBehavior">
                
                <webHttp helpEnabled="true" faultExceptionEnabled="true" defaultBodyStyle="Bare"/>
              <newtonsoftJsonBehavior />
              </behavior>

这样以后就可以使用我们大家都喜欢的newtonjson来序列化反序列化json了:


如果需要把时间日期格式定义成成yyyy-MM-dd HH:mm:ss的格式(newton是格式化成yyyy-MM-ddTHH:mm:ssT)的,则可以修改NewtonsoftJsonDispatchFormatter.cs的代码:DeserializeRequest方法中的:

            Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer() {
                DateFormatString = "yyyy-MM-dd HH:mm:ss"
            };
SerializeReply方法中的:

                    using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw) { DateFormatString ="yyyy-MM-dd HH:mm:ss"})
                    {

同时,可以在正式环境中把SerializeReply方法中的如下这样注释掉,以减少传输数据大小:

//writer.Formatting = Newtonsoft.Json.Formatting.Indented;

这种配置方式没有找到可以在config文件中直接配置json输出格式和日期时间格式的方法,貌似WCF自定义行为扩展是不支持自定义属性的xml配置的,如果可以的话

能配置成

<newtonsoftJsonBehavior JsonFormatter="None" DateTimeFormatter="yyyy-MM-dd HH:mm:ss"/>

就完美了,可惜解析的时候就过不去


此文相关的代码现在已经传到oschina上了

http://git.oschina.net/juncos/REST4SqlServer

这是一个https的Windows服务,用于通过此REST服务执行sql语句

在App.config中需要指定https绑定的证书,和服务URL(现在为XXX.xxx.xxx.xx)

此证书可以自己通过Openssl或者.net的mkcert自己制作



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值