向客户端提供JSON数据的方式

契约的定义, 在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; }
相关推荐
前网易架构师-高司机5 小时前
带标注的扑克牌识别数据集,识别率99.5%,3083张图,支持yolo,coco json,voc xml,文末有模型训练代码
xml·yolo·json·数据集·数字·扑克牌·纸牌
前网易架构师-高司机5 小时前
带标注的浮游藻类24种数据集,识别率91.5 %数据集, 23175张图,支持yolo,coco json,voc xml,文末有模型训练代码
yolo·json·数据集·微观·生物·浮游·藻类
维天说21 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
一颗小行星-2 天前
为什么有的JSON可以带注释?
json
CedarQR3 天前
万字长文:从零在 RK3588 上部署 PaddleSpeech 中文 TTS 全流程(FastSpeech2 + HiFiGAN)
开发语言·c++·嵌入式硬件·ubuntu·json
Geoking.4 天前
JSON vs JSONL:从数据格式到 AI Agent 的工程实践
人工智能·深度学习·json
ID_180079054734 天前
京东商品详情API能力解析与标准化应用方案(含JSON返回示例)
json
灯澜忆梦5 天前
Go 语言 _JSON---序列化与反序列化
开发语言·golang·json
梦幻通灵6 天前
Notepad++格式化Json两种方案【持续更新】
android·json·notepad++
解局易否结局6 天前
鸿蒙原生开发实战|Native JSON 编解码与高性能数据序列化
华为·json·harmonyos