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. Django-02路由层

    U RL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代 ...

  2. path的用法和所遇错误

    首先上源代码: def _path(route, view, kwargs=None, name=None, Pattern=None): if isinstance(view, (list, tup ...

  3. PHP程序执行流程

    1, PHP文件一定放在服务器的,但是PHP中不同的内容会在不同的地方执行.下图演示了浏览器请求一个php页面的流程. 2,时序图如下所示,在浏览器中输入url后,首先去本机hosts文件中解析ip地 ...

  4. CentOS下TFTP服务安装

    CentOS下TFTP服务安装 今天和同学做交换机恢复DCN操作系统的任务,然后需要用到tftp,然后就开始研究.这里对TFTP服务进行介绍以及安装. tftp 比 ftp 更易于管理 tftp 比 ...

  5. python模块之——tqdm(进度条)

    from tqdm import tqdm for i in tqdm(range(10000)): """一些操作""" pass 效果: ...

  6. POJ-2251-Dungeon Master(3D迷宫,BFS)

    Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 48111   Accepted: 18149 ...

  7. UltraFast设计法实践(1) -- 初始设计检查

    目录 1. report_failfast 1.1 命令使用 1.2 优化 1.3.总结 2.report_timing_summary 3. report_methodology 4. 总结 5.遗 ...

  8. MySQL:管理MySQL、事务(三)

    干货: 命令行程序mysql实际上是MySQL客户端,真正的MySQL服务器程序是mysqld,在后台运行. 数据库事务具有ACID特性,用来保证多条SQL的全部执行. 五.MySQL 通过mysql ...

  9. 常见浏览器hack汇总

    1.背景渐变bug: ①.ie8 ie9:用滤镜的方式解决: -ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientT ...

  10. train loss与test loss结果分析

    train loss 不断下降,test loss不断下降,说明网络仍在学习; train loss 不断下降,test loss趋于不变,说明网络过拟合; train loss 趋于不变,test ...