用JSON做數(shù)據(jù)傳輸格式中的一些問題總結(jié)
一. 用WCF提供Json數(shù)據(jù)
用WCF向客戶端提供Json數(shù)據(jù)我們需要注意,
A. 契約的定義, 在WebInvokeAttribute 或者 WebGetAttribute中的ResponseFormat設(shè)置為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 數(shù)據(jù)
1. 在ValueProviderFactories.Factories.Add(new JsonValueProviderFactory())中加入 Json 數(shù)據(jù)的處理, MVC 3默認(rèn)是加入的, 如果你使用的是 MVC3, 則無(wú)需理會(huì)這一點(diǎn).
2. 采用JsonResult作為你Action的返回值。
3.返回是使用return Json(XXX); XXX為你要返回的數(shù)據(jù),其數(shù)據(jù)類型必須為可序列化類型.
三. 可采用以asmx為后綴名的簡(jiǎn)單WebService來(lái)實(shí)現(xiàn),
四. 使用HttpHandler機(jī)制來(lái)實(shí)現(xiàn).
因?yàn)閃CF已被微軟定義為微軟系下的通信平臺(tái),而后兩種隨可以實(shí)現(xiàn),但是是較早的實(shí)現(xiàn)方式,所以在此我使用了WCF,直接把所提供的數(shù)據(jù),視作系統(tǒng)的數(shù)據(jù)提供接口.
而在.NET MVC的環(huán)境里, 已經(jīng)直接支持輸出 Json 形式的數(shù)據(jù),所以在非.NET MVC的環(huán)境選擇WCF提供, 而在.NET MVC環(huán)境直接選擇用JSON Action支持.
WEB客戶端處理
用JQuery Ajax處理
把 dataType設(shè)置為 'json' 格式,在接收數(shù)據(jù)時(shí)會(huì)自動(dòng)把result轉(zhuǎn)換為json object格式.
$.ajax({
url: ‘urladdress'
type: 'GET',
contentType: 'application/json',
dataType: 'json',
cache: false,
async: false,
error: JQueryAjaxErrorHandler,
success: function (result) { }
});
異常處理的考慮
在這里我主要考慮在Web環(huán)境下異常的處理, 根據(jù)HTTP協(xié)議的定義, 每次請(qǐng)求都會(huì)返回一個(gè) HTTP Status Code , 不同的Code代表了不同的意義。因此我們的Web應(yīng)用程序也應(yīng)該是這樣,根據(jù)不同的結(jié)果返回不同的 HTTP Status Code , 比如200,代表服務(wù)端正確的返回,417代表我們期望的服務(wù)端異常,404,請(qǐng)求不存在等, 以及301我們的未授權(quán)。
在WCF環(huán)境下,我們首先要給每個(gè)方法添加 FaultContract, 如下:
FaultContract(typeof(WebFaultException<WebErrorDetail>))
其次我們要對(duì)異常做一些處理,讓服務(wù)端能返回正確的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; }
}
因?yàn)槲覀冊(cè)贘SON做數(shù)據(jù)傳輸?shù)臅r(shí)候, DataContract中的IsReference是不可以為true的,其意思是相對(duì)于XML來(lái)說(shuō)的,XML是可以支持?jǐn)?shù)據(jù)的循環(huán)引用, 而JSON是不支持的,所以WebFaultJsonFormatException的作用就在于判斷當(dāng)前我們的JSON數(shù)據(jù)類型的DataContract的IsReference是否為true, 如果是,則返回一個(gè)我們定義好的錯(cuò)誤信息. 如果沒有采用這個(gè)定義,JQUery Ajax因此問題接收到的 HTTP Status Code 是15???的一個(gè)錯(cuò)誤代碼, 但這個(gè)錯(cuò)誤代碼并不是我們正常的 HTTP Status Code 范圍.
異常處理的一個(gè)誤區(qū)
最早的時(shí)候,由于沒想到用這個(gè)方式處理,也是長(zhǎng)久寫代碼犯下的一個(gè)弊病, 給每個(gè)方法加了一個(gè)固定的泛型返回值類型
[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; }
}
每次返回都會(huì)有一個(gè)Success代表是否成功, ErrorMessage代表錯(cuò)誤情況下的錯(cuò)誤信息, 這樣做的方式其實(shí)就是每次返回的 HTTP Status Code 都是200, 后來(lái)知道想到上面的解決辦法之后,才覺得我們更本不需要搞的這么復(fù)雜,既然是Web, 那干嗎不把程序?qū)懙母螲TTP協(xié)議的定義, 那樣豈不更簡(jiǎn)單。
所以在此也體會(huì)到各種標(biāo)準(zhǔn)的好處, 熟悉標(biāo)準(zhǔn),熟悉編程模型及各種API, 我們的開發(fā)會(huì)更簡(jiǎn)單,更輕松.
以上都是按個(gè)人理解所寫,有不對(duì)之處請(qǐng)指正.
相關(guān)文章
JS解析后臺(tái)返回的JSON格式數(shù)據(jù)實(shí)例
今天小編就為大家分享一篇JS解析后臺(tái)返回的JSON格式數(shù)據(jù)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2018-08-08JSON 和 JavaScript eval使用說(shuō)明
JSON (JavaScript Object Notation) 一種輕量級(jí)的數(shù)據(jù)交換格式,比 XML 更輕巧,JSON 是JavaScript 原生格式,這意味著 JavaScript 中處理 JSON 數(shù)據(jù)不需要任何 API 和工具包。2010-06-06詳解Java中String JSONObject JSONArray List<實(shí)體類>轉(zhuǎn)換
這篇文章主要介紹了詳解String JSONObject JSONArray List<實(shí)體類>轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11JSON 學(xué)習(xí)之JSON in JavaScript詳細(xì)使用說(shuō)明
只需要在前臺(tái)頁(yè)面中引入相應(yīng)的javascript即可測(cè)試2010-02-02json的定義、標(biāo)準(zhǔn)格式及json字符串檢驗(yàn)
今天分享和總結(jié)一些json的基本定義、格式、字符串的格式,以及在做測(cè)試的時(shí)候使用json時(shí)做一些簡(jiǎn)單的校驗(yàn)2014-05-05json-lib出現(xiàn)There is a cycle in the hierarchy解決辦法
如果需要解析的數(shù)據(jù)間存在級(jí)聯(lián)關(guān)系,而互相嵌套引用,在hibernate中極容易嵌套而拋出net.sf.json.JSONException: There is a cycle in the hierarchy異常。2010-02-02JSON.parse 數(shù)據(jù)不完整的解決方法
本文主要介紹了JSON.parse 數(shù)據(jù)不完整的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07