`
yzd
  • 浏览: 1818560 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

在Web数据处理方面已经占据了一定的位置,这段时间涉及到用Json做为数据传输格式的项目有3个,其中有部分页面就采用了Json 数据传输格式, 这里我总结下这段时间采用这种方式的一些问题总结,

向客户端提供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, 我们的开发会更简单,更轻松.

以上都是按个人理解所写,有不对之处请指正.

0
1
分享到:
评论

相关推荐

    Json转换程序

    Json序列化和反序列化。网络中数据传输经常是json,现在做的一个项目返回json格式数据的接口,通过例子由易到难总结一下处理过程,希望能帮到和我一样开始不会的朋友。

    JSON详解.pptx

    很好的总结了json的使用方法,很好的学习资料。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

    JSON教程+应用讲解资源合集

    JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言...

    json原理分析及实例介绍

    这次在项目中前后台的数据交互中用到了json,经过这段时间的使用,大概了解了一下,简单总结一下json。 JSON:JavaScript 对象表示法(JavaScript Object Notation)。 JSON 是存储和交换文本信息的语法。类似 XML。...

    python中的json总结

    JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次...

    c#处理3种json数据的实例

    网络中数据传输经常是xml或者json,现在做的一个项目之前调其他系统接口都是返回的xml格式,刚刚遇到一个返回json格式数据的接口,通过例子由易到难总结一下处理过程,希望能帮到和我一样开始不会的朋友。...

    基于$.ajax()方法从服务器获取json数据的几种方式总结

    json是一种取代xml的数据结构,和xml相比,它更小巧但描述能力却很强,网络传输数据使用流量更少,速度更快。 json就是一串字符串,使用下面的符号标注。 {键值对} : json对象 [{},{},{}] :json数组 “” :双引号...

    对比分析json及XML

     最近一段时间,个人综合了之前对XML、JSON的一些了解,参考了相关资料,再结合视频的代码,把自己的一些思考融入了这篇总结文档中,同时尝试用通俗诙谐的语言风格来阐述,期望能给感兴趣的读者带来帮助。...

    JS操作JSON详细总结

    在JS中将JSON的字符串解析成JSON数据格式,一般有两种方式: 1.一种为使用eval_r()函数。 2. 使用Function对象来进行返回解析。 在数据传输流程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以...

    ajax数据传输方式实例详解

    主要介绍了ajax数据传输方式,结合实例形式较为详细的分析总结了ajax数据传输的原理与传输文本、xml及json格式数据的具体实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    深入浅析Android JSON解析

    android中网络数据传输是经常被用到的,通常我们使用xml或者json,而json更加轻量,便捷,我们使用的更多。我自己在项目中使用很多,今天就说说android中怎么去解析JSON,帮助自己总结内容,同时帮助别人少走弯路

    JSON学习小结

    尽管【JSON】是【JavaScript】的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯 { firstName:Tom, lastName:Smith, sex:male, age:23, married:false, address: { ...

    学习ajax必看ppt--总结的很全面看描述

    01_Ajax基础;02_使用Ajax发送异步请求;03_在请求和响应中使用XML;04_使用JSON进行数据传输;对XML文档进行分析

    《Android应用开发》个人总结报告.doc

    对Request发送,Response处理 中通过比较方便的JSON对象传输,以及对XML、JSON、图片、业务等下载处理,对API接 口调用等问题处理。 首先在界面上,我们同样可以通过不同布局进行设计非常酷的界面,这些界面可以通 ...

    assignment3-stockquotes:2015年SpringCRIA WT课程的作业3

    没有页面刷新,但是例如带有价格信息的div总是更新该页面必须完全使用JavaScript构建,从一个空页面开始使用JSON进行数据传输单元测试,每种方法至少一项测试在客户端目录的README.md中记录使用概念###炫耀画布的...

    基于Android的毕业论文管理系统的设计与研究.docx

    数据传输的采取的技术是JSON技术,JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON是完全独立的文本格式,而且还使用了一个语言习惯类似C家族(包括C,C+ +,C#,Java中的JavaScript,Perl,Python...

    解决angular的$http.post()提交数据时后台接收不到参数值问题的方法

    写此文的目的:通过上面提到的文章中的解决之道,结合自己的经验,总结了如下发现。 前端:html,jquery,angular 后端:java,springmvc 一、平常使用的post提交和接收方式 前端使用jquery提交数据。 $.ajax({ ...

    30条android项目开发技巧与经验总结

    2、使用json用作网络数据传输时,应该使用String字段取代int字段。 3、按照现在正常密度比(系统的densityDPI根据分辨率和屏幕尺寸为正常的120、160、240、320、480、640时)9:16的安卓机其尺寸为(360dp*540dp)。...

Global site tag (gtag.js) - Google Analytics