作家
登录

用JSON做数据传输格式中的一些问题总结

作者: 来源:www.28hudong.com 2013-03-30 00:36:59 阅读 我要评论

向客户端提供JSON数据的方式 一. 用WCF提供Json数据 用WCF向客户端提供Json数据我们需要注意, A. 契约的定义, 在WebInvokeAttribute 或者 WebGetAttribute中的ResponseFormat设置为WebMessageForm.Json, 复制代码 代码如下: [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "IsExistSSID/{SSID}", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] B. EndPointBehavior使用WebHttp 复制代码 代码如下: <behavior name="UIAjaxEndpointBehavior"> <webHttp /> <PolicyEndPointBehavior /> </behavior> C. Binding 方式使用webHttpBinding 复制代码 代码如下: <service name="XX.DeviceUIService" behaviorConfiguration="UIAjaxServiceBehavior"> <endpoint address="" behaviorConfiguration="UIAjaxEndpointBehavior" binding="webHttpBinding" contract="DeviceUIServiceContract" /> </service> 二. 用.Net MVC Action提供 JSON 数据 1. 在ValueProviderFactories.Factories.Add(new JsonValueProviderFactory())中加入 Json 数据的处理, MVC 3默认是加入的, 如果你使用的是 MVC3, 则无需理会这一点. 2. 采用JsonResult作为你Action的返回值。 3.返回是使用return Json(XXX); XXX为你要返回的数据,其数据类型必须为可序列化类型. 三. 可采用以asmx为后缀名的简单WebService来实现, 四. 使用HttpHandler机制来实现. 因为WCF已被微软定义为微软系下的通信平台,而后两种随可以实现,但是是较早的实现方式,所以在此我使用了WCF,直接把所提供的数据,视作系统的数据提供接口. 而在.NET MVC的环境里, 已经直接支持输出 Json 形式的数据,所以在非.NET MVC的环境选择WCF提供, 而在.NET MVC环境直接选择用JSON Action支持. WEB客户端处理 用JQuery Ajax处理 把 dataType设置为 'json' 格式,在接收数据时会自动把result转换为json object格式. 复制代码 代码如下: $.ajax({ url: ‘urladdress' type: 'GET', contentType: 'application/json', dataType: 'json', cache: false, async: false, error: JQueryAjaxErrorHandler, success: function (result) { } }); 异常处理的考虑 在这里我主要考虑在Web环境下异常的处理, 根据HTTP协议的定义, 每次请求都会返回一个 HTTP Status Code , 不同的Code代表了不同的意义。因此我们的Web应用程序也应该是这样,根据不同的结果返回不同的 HTTP Status Code , 比如200,代表服务端正确的返回,417代表我们期望的服务端异常,404,请求不存在等, 以及301我们的未授权。在WCF环境下,我们首先要给每个方法添加 FaultContract, 如下: FaultContract(typeof(WebFaultException<WebErrorDetail>)) 其次我们要对异常做一些处理,让服务端能返回正确的HTTP Status Code. 复制代码 代码如下: try { //BussinessCode..... } catch (DuplicateException ex) { throw new WebFaultJsonFormatException<WebErrorDetail>(new WebErrorDetail(ex.Message, ex), HttpStatusCode.ExpectationFailed); } catch (NotExistException ex) { throw new WebFaultJsonFormatException<WebErrorDetail>(new WebErrorDetail(ex.Message, ex), HttpStatusCode.ExpectationFailed); } catch (AppException ex) { throw new WebFaultJsonFormatException<WebErrorDetail>(new WebErrorDetail(ex.Message, ex), HttpStatusCode.ExpectationFailed); } catch (Exception ex) { throw new WebFaultJsonFormatException<WebErrorDetail>(new WebErrorDetail(ex.Message, ex), HttpStatusCode.ExpectationFailed); } 其中WebFaultJsonFormatException的签名如下: [Serializable, DataContract] public class WebFaultJsonFormatException<T> : WebFaultException<T> { public WebFaultJsonFormatException(T detail, HttpStatusCode statusCode) : base(detail, statusCode) { ErrorDetailTypeValidator(detail); } public WebFaultJsonFormatException(T detail, HttpStatusCode statusCode, IEnumerable<Type> knownTypes) : base(detail, statusCode, knownTypes) { ErrorDetailTypeValidator(detail); } private void ErrorDetailTypeValidator(T detail) { foreach (DataContractAttribute item in detail.GetType().GetCustomAttributes(typeof(DataContractAttribute), true)) { if (item.IsReference) throw new WebFaultJsonFormatException<PureWebErrorDetail>(new PureWebErrorDetail("The DataContractAttribute property 'IsReference' which applied on {0} can't be true when the transfer code type is JSON fromat.", typeof(T).FullName), HttpStatusCode.ExpectationFailed); } } } [Serializable, DataContract(IsReference = false)] public class PureWebErrorDetail { public PureWebErrorDetail(string message, params object[] args) { this.Message = string.Format(message, args); } [DataMemberAttribute] public string Message { get; set; } } 因为我们在JSON做数据传输的时候, DataContract中的IsReference是不可以为true的,其意思是相对于XML来说的,XML是可以支持数据的循环引用, 而JSON是不支持的,所以WebFaultJsonFormatException的作用就在于判断当前我们的JSON数据类型的DataContract的IsReference是否为true, 如果是,则返回一个我们定义好的错误信息. 如果没有采用这个定义,JQUery Ajax因此问题接收到的 HTTP Status Code 是15???的一个错误代码, 但这个错误代码并不是我们正常的 HTTP Status Code 范围.异常处理的一个误区 最早的时候,由于没想到用这个方式处理,也是长久写代码犯下的一个弊病, 给每个方法加了一个固定的泛型返回值类型 复制代码 代码如下: [DataContract] public class TmResult { [DataMember] public bool Success { get; set; } [DataMember] public string ErrorMessage { get; set; } [DataMember] public string FullMessage { get; set; } [DataMember] public string CallStack { get; set; } } [DataContract] public class TmResult<T> : TmResult where T : class { [DataMember] public T Model { get; set; } } 每次返回都会有一个Success代表是否成功, ErrorMessage代表错误情况下的错误信息, 这样做的方式其实就是每次返回的 HTTP Status Code 都是200, 后来知道想到上面的解决办法之后,才觉得我们更本不需要搞的这么复杂,既然是Web, 那干吗不把程序写的更符合HTTP协议的定义, 那样岂不更简单。 所以在此也体会到各种标准的好处, 熟悉标准,熟悉编程模型及各种API, 我们的开发会更简单,更轻松. 以上都是按个人理解所写,有不对之处请指正.

  推荐阅读

  用jQuery模拟页面加载进度条的实现代码

因为我们无法通过任何方法获取整个页面的大小和当前加载了多少,所以想制作一个加载进度条的唯一办法就是模拟。那要怎么模拟呢?   我们知道,页面是从上往下执行的,也就是说我们可以大致估算出在页面的某个位置>>>详细阅读


本文标题:用JSON做数据传输格式中的一些问题总结

地址:http://www.17bianji.com/kaifa2/JS/23812.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)