DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JSON基礎 >> 用JSON做數據傳輸格式中的一些問題總結
用JSON做數據傳輸格式中的一些問題總結
編輯: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, 我們的開發會更簡單,更輕松.
以上都是按個人理解所寫,有不對之處請指正.

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved