wcf 内置的json序列化工具,有时需要替换,或者特殊情况的处理,需要修改。

我也遇到了Dto属性类型是datetime,json的反序列化 和 序列号不友好。

这是国外网站的一个方案:Replacing WCF DataContractJsonSerializer with Newtonsoft JsonSerializer

不过时间格式还不是我想要的,他是发布在GitHub上,于是简单修改了时间格式,使更符合国情。

需要引用新写的库  WcfNewtonsoftJsonSerializer ,然后配置文件配置好。

关键配置部分:behaviorExtensions、endpointBehaviors、webHttpBinding

   <system.serviceModel>

     <extensions>
<behaviorExtensions>
<add name="newtonsoftJsonBehavior" type="WcfNewtonsoftJsonSerializer.NewtonsoftJsonBehaviorExtension, WcfNewtonsoftJsonSerializer" />
</behaviorExtensions>
</extensions> <behaviors>
<endpointBehaviors>
<behavior name="restEndPointBehavior">
<webHttp helpEnabled="true" />
<newtonsoftJsonBehavior />
</behavior>
</endpointBehaviors> <serviceBehaviors>
<behavior name="restServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="restWebHttpBinding"
contentTypeMapper="WcfNewtonsoftJsonSerializer.NewtonsoftJsonContentTypeMapper, WcfNewtonsoftJsonSerializer"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxBufferSize="2147483647"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:02:00"
sendTimeout="00:02:00"
maxReceivedMessageSize="2147483647"
transferMode="Buffered">
<security mode="None">
<transport clientCredentialType="None" />
</security>
<readerQuotas maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxDepth="2147483647"
maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
</webHttpBinding>
</bindings> <services>
<service name="WcfService1.Service1" behaviorConfiguration="restServiceBehavior">
<endpoint address=""
contract="WcfService1.IService1"
binding="webHttpBinding"
bindingConfiguration="restWebHttpBinding"
behaviorConfiguration="restEndPointBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services> </system.serviceModel>

以下是WcfNewtonsoftJsonSerializer项目的关键代码:

     public class NewtonsoftJsonBehavior : WebHttpBehavior
{
public override void Validate( ServiceEndpoint endpoint )
{
base.Validate( endpoint ); var elements = endpoint.Binding.CreateBindingElements();
var webEncoder = elements.Find<WebMessageEncodingBindingElement>();
if ( webEncoder == null )
{
throw new InvalidOperationException( "This behavior must be used in an endpoint with the WebHttpBinding (or a custom binding with the WebMessageEncodingBindingElement)." );
} foreach ( var operation in endpoint.Contract.Operations )
{
ValidateOperation( operation );
}
} protected override IDispatchMessageFormatter GetRequestDispatchFormatter( OperationDescription operationDescription, ServiceEndpoint endpoint )
{
if ( IsGetOperation( operationDescription ) )
{
// no change for GET operations
return base.GetRequestDispatchFormatter( operationDescription, endpoint );
} if ( operationDescription.Messages[].Body.Parts.Count == )
{
// nothing in the body, still use the default
return base.GetRequestDispatchFormatter( operationDescription, endpoint );
} return new NewtonsoftJsonDispatchFormatter( operationDescription, true );
} protected override IDispatchMessageFormatter GetReplyDispatchFormatter( OperationDescription operationDescription, ServiceEndpoint endpoint )
{
if ( operationDescription.Messages.Count == || operationDescription.Messages[].Body.ReturnValue.Type == typeof( void ) )
{
return base.GetReplyDispatchFormatter( operationDescription, endpoint );
}
else
{
return new NewtonsoftJsonDispatchFormatter( operationDescription, false );
}
} private void ValidateOperation( OperationDescription operation )
{
if ( operation.Messages.Count > )
{
if ( operation.Messages[].Body.Parts.Count > )
{
throw new InvalidOperationException( "Operations cannot have out/ref parameters." );
}
} var bodyStyle = GetBodyStyle( operation );
var inputParameterCount = operation.Messages[].Body.Parts.Count;
if ( !IsGetOperation( operation ) )
{
var wrappedRequest = bodyStyle == WebMessageBodyStyle.Wrapped || bodyStyle == WebMessageBodyStyle.WrappedRequest;
if ( inputParameterCount == && wrappedRequest )
{
throw new InvalidOperationException( "Wrapped body style for single parameters not implemented in this behavior." );
}
} var wrappedResponse = bodyStyle == WebMessageBodyStyle.Wrapped || bodyStyle == WebMessageBodyStyle.WrappedResponse;
var isVoidReturn = operation.Messages.Count == || operation.Messages[].Body.ReturnValue.Type == typeof( void );
if ( !isVoidReturn && wrappedResponse )
{
throw new InvalidOperationException( "Wrapped response not implemented in this behavior." );
}
} private WebMessageBodyStyle GetBodyStyle( OperationDescription operation )
{
var wga = operation.Behaviors.Find<WebGetAttribute>();
if ( wga != null )
{
return wga.BodyStyle;
} var wia = operation.Behaviors.Find<WebInvokeAttribute>();
if ( wia != null )
{
return wia.BodyStyle;
} return DefaultBodyStyle;
} private bool IsGetOperation( OperationDescription operation )
{
var wga = operation.Behaviors.Find<WebGetAttribute>();
if ( wga != null )
{
return true;
} var wia = operation.Behaviors.Find<WebInvokeAttribute>();
if ( wia != null )
{
return wia.Method == "HEAD";
} return false;
}
}
     public class NewtonsoftJsonBehaviorExtension : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof ( NewtonsoftJsonBehavior ); }
} protected override object CreateBehavior()
{
return new NewtonsoftJsonBehavior();
}
}
     public class NewtonsoftJsonContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType( string contentType )
{
return WebContentFormat.Raw;
}
}
     public class NewtonsoftJsonDispatchFormatter : IDispatchMessageFormatter
{
private readonly OperationDescription _operation;
private readonly Dictionary<string, int> _parameterNames; public NewtonsoftJsonDispatchFormatter( OperationDescription operation, bool isRequest )
{
_operation = operation;
if ( isRequest )
{
var operationParameterCount = operation.Messages[].Body.Parts.Count;
if ( operationParameterCount > )
{
_parameterNames = new Dictionary<string, int>();
for ( var i = ; i < operationParameterCount; i++ )
{
_parameterNames.Add( operation.Messages[].Body.Parts[i].Name, i );
}
}
}
} public void DeserializeRequest( Message message, object[] parameters )
{
object bodyFormatProperty;
if ( !message.Properties.TryGetValue( WebBodyFormatMessageProperty.Name, out bodyFormatProperty ) ||
( bodyFormatProperty as WebBodyFormatMessageProperty ).Format != WebContentFormat.Raw )
{
throw new InvalidOperationException( "Incoming messages must have a body format of Raw. Is a ContentTypeMapper set on the WebHttpBinding?" );
} var bodyReader = message.GetReaderAtBodyContents();
bodyReader.ReadStartElement( "Binary" );
var rawBody = bodyReader.ReadContentAsBase64();
var ms = new MemoryStream( rawBody ); var sr = new StreamReader( ms );
var serializer = new Newtonsoft.Json.JsonSerializer();
if ( parameters.Length == )
{
// single parameter, assuming bare
parameters[] = serializer.Deserialize( sr, _operation.Messages[].Body.Parts[].Type );
}
else
{
// multiple parameter, needs to be wrapped
Newtonsoft.Json.JsonReader reader = new Newtonsoft.Json.JsonTextReader( sr );
reader.Read();
if ( reader.TokenType != Newtonsoft.Json.JsonToken.StartObject )
{
throw new InvalidOperationException( "Input needs to be wrapped in an object" );
} reader.Read();
while ( reader.TokenType == Newtonsoft.Json.JsonToken.PropertyName )
{
var parameterName = reader.Value as string;
reader.Read();
if ( _parameterNames.ContainsKey( parameterName ) )
{
var parameterIndex = _parameterNames[parameterName];
parameters[parameterIndex] = serializer.Deserialize( reader, _operation.Messages[].Body.Parts[parameterIndex].Type );
}
else
{
reader.Skip();
} reader.Read();
} reader.Close();
} sr.Close();
ms.Close();
} public Message SerializeReply( MessageVersion messageVersion, object[] parameters, object result )
{
byte[] body;
var serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Converters.Add( new IsoDateTimeConverter() {DateTimeFormat = "yyyy-MM-dd HH:mm:ss", DateTimeStyles = DateTimeStyles.None} ); using ( var ms = new MemoryStream() )
{
using ( var sw = new StreamWriter( ms, Encoding.UTF8 ) )
{
using ( Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter( sw ) )
{
//writer.Formatting = Newtonsoft.Json.Formatting.Indented;
serializer.Serialize( writer, result );
sw.Flush();
body = ms.ToArray();
}
}
} var replyMessage = Message.CreateMessage( messageVersion, _operation.Messages[].Action, new RawBodyWriter( body ) );
replyMessage.Properties.Add( WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty( WebContentFormat.Raw ) );
var respProp = new HttpResponseMessageProperty();
respProp.Headers[HttpResponseHeader.ContentType] = "application/json";
replyMessage.Properties.Add( HttpResponseMessageProperty.Name, respProp );
return replyMessage;
}
}
     public class RawBodyWriter : BodyWriter
{
private readonly byte[] _content; public RawBodyWriter( byte[] content )
: base( true )
{
_content = content;
} protected override void OnWriteBodyContents( XmlDictionaryWriter writer )
{
writer.WriteStartElement( "Binary" );
writer.WriteBase64( _content, , _content.Length );
writer.WriteEndElement();
}
}

wcf datetime json format的更多相关文章

  1. 最新版ABP 动态WebAPI 日期转json带T的解决方案| ABP DateTIme Json format

    ABP动态webapi返回的json数据中,日期时间带T还有毫秒数的问题,在以往的版本中可以使用下面方法解决: 在XXXAbpWebApiModule中加上下面的代码: 很老的很老的版本有效: pub ...

  2. SpringMVC 设置全局DateTime json返回格式

    对于部分返回DateTime的项目,只需要在指定属性上添加@JsonSerialize 使用自定义的json转换格式即可自定义返回DateTime格式 但是对于项目中返回有多个DateTime字段来说 ...

  3. WCF Ajax Json的应用

    WCF Ajax 的应用网上实际上有很多, 如: Ajax与Wcf交互-JSON jQuery调用WCF服务传递JSON对象 WCF以Json格式返回对象,客户端以JS调用显示 关于SoapUI的介绍 ...

  4. 解决asp.net core 日期格式 datetime Json返回 带T的问题

    原文:解决asp.net core 日期格式 datetime Json返回 带T的问题 记录一下: Startup中,将 services.AddMvc(); 改为: services.AddMvc ...

  5. WCF JSON DATETIME JSON.NET (Newtonsoft.Json.dll)

    [DataMember] public DateTime? myTime { get; set; } var timeFormat = new JsonSerializerSettings() { D ...

  6. WCF 生产json对外的接口

    调用wcf public ActionResult Index() { ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序."; WC ...

  7. python模块time&datetime&json & picle&14.logging等

    本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...

  8. Entity Framework + WCF REST JSON Service

    利用EF 和WCF 建立一个REST JSON Service. 首先我们要下载一个Visual Studio 的Template 叫 "ADO.NET C# POCO Entity Gen ...

  9. WCF返回JSON的详细配置

    开发环境:VS2008,c# 1.新建个WCF服务网站 文件-新建-网站-WCF服务 2,运行一下,提示配置WEB.CONFIG,点击确认. 3,打开web.config增加如下节点: <ser ...

随机推荐

  1. fatal: Authentication failed for又不弹出用户名和密码 解决办法

    各位,如果能弹出来,一定是你账号密码搞错了,就别继续看了.   image.png 切换命令行:   image.png 依然报错, 说到这个问题,又可以长篇大论了, 我使用的是tortoisegit ...

  2. 用户画像,知乎Live总结

    ttps://www.zhihu.com/lives/889189116527403008/messages 用户画像两层含义:单个标签:用户的分布 标签体系要与时俱进,如果标签被下游强依赖,则不轻易 ...

  3. 为什么程序员都不喜欢使用switch而使用if来做条件跳转

    请用5秒钟的时间查看下面的代码是否存在bug.   OK,熟练的程序猿应该已经发现Bug所在了,在第8行和第10行下面我没有添加关键字break; 这就导致这段代码的行为逻辑与我的设计初衷不符了. 缺 ...

  4. bzoj1009GT考试

    题目链接 没啥好说的,矩阵优化+$kmp$字符串匹配 上代码: /************************************************************** Prob ...

  5. php面试题汇集2

    1.实现中文字符串截取无乱码方法 开启mbstring扩展,然后自定义函数: <?php header('content-Type:text/html:charset=utf-8'); func ...

  6. Archlinux下virtualbox报错'/sbin/rcvboxdrv setup'

    因为刚刚换成archlinux系统,安装virtualbox的时候报错了.如下图: 可是怎么解决呢?我看了很多资料大多数是ubuntu的,没有archlinux的. 但是原理都差不多我借着也就研究出来 ...

  7. css里面鼠标的形状-----》easyui哪点事

    用css控制鼠标样式的语法如下:<span style="cursor:*">文本或其它页面元素</span>把 * 换成如下15个效果的一种: 下面是对这 ...

  8. python3的enumerate函数

    enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中.

  9. pop控制器

    1.寻找指定的控制器MineViewControllerclass UIViewController *mineVC = nil; for (UIViewController * controller ...

  10. celery简单理解和使用

    解决同步阻塞的问题 将耗时任务放到后台异步执行,不影响用户其他操作. 实现原理 任务队列是一种跨线程,跨机器的机制. 任务队列中包含称作任务的工作单元.有专门的进程持续不断的监视任务队列,并从中得到新 ...