AJAX JSON中日期類型DateTime格式化的序列化自訂對象以及自訂型別參數的問題處理

來源:互聯網
上載者:User

首先看一下ASP.NET AJAX伺服器端對日期類型JSON序列化的處理:(詳見Ajax擴充源碼中的JavaScriptSerializer.cs)

internal static readonly long DatetimeMinTimeTicks = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Ticks;
private static void SerializeDateTime(DateTime datetime, StringBuilder sb) {
            
        sb.Append(@"""//Date(");
        sb.Append((datetime.ToUniversalTime().Ticks - DatetimeMinTimeTicks) / 10000);
        sb.Append(@")//""");
}

最早期,微軟使用下面方法進行序列化:

ASP.NEXT 中的 AJAX JSON 序列化程式將 DateTime 執行個體編碼為 JSON 字串。在預發布周期中,ASP.NET AJAX 使用格式“@ticks@”,其中 ticks 表示從通用協調時間 (UTC) 1970 年 1 月 1 日起經過的毫秒數。以 UTC 表示的日期和時間(如 1989 年 11 月 29 日 4:55:30 AM)會編碼為“@62831853071@”。雖然簡單易懂,但此格式無法區分序列化的日期和時間值與看起來像序列化日期但又不需要進行還原序列化的值。因此,ASP.NET AJAX 團隊對最終版本進行了更改,通過採用“//Date(ticks)//”格式解決了這一問題。

新格式藉助一個小技巧減少了誤解的可能性。在 JSON 中,字串中的正斜杠 (/) 字元可以用反斜線 (/)
進行轉義(即使沒有對此進行嚴格要求)。ASP.NET AJAX 團隊利用這點修改了 JavaScriptSerializer,將
DateTime 執行個體編寫為字串“//Date(ticks)//”。兩個正斜杠的轉義只是表面的,但對 JavaScriptSerializer 至關重要。按照 JSON 規則,“//Date(ticks)//” 在技術上相當於 “/Date(ticks)/”,但 JavaScriptSerializer 會將前者還原序列化為 DateTime,將後者還原序列化為 String。因此與預發布版本的“@ticks@”格式相比,混淆的可能性會大大減少。

註:此段文字來源於MSDN文章《JavaScript 和 .NET 中的 JavaScript Object Notation (JSON) 簡介》

這裡我要補充一個技巧,大家知道,在document中如果出現<script>和</script>那麼腳步解譯器就會對其中文本進行解析,所以如果你編寫下面的代碼,則會提示錯誤:

<script>
document.write("<script>alert(1);</script>");
</script>

因為中間出現了“</script>”這樣的代碼,那麼我們可以使用:

<script>
document.write("<script>alert(1);</scr"+"ipt>");
</script>

來避免這種錯誤,這時我們還可以使用“/”來轉義:

<script>
document.write("<script>alert(1);<//script>");
</script>

-----------------------------------------------------------------------------------------------------

執行個體解決:

 Class rssItem

               [Property(NotNull = true, Column = "PubDate")]
        public virtual DateTime PubDate
        {
            get { return _pubDate; }
            set { _pubDate = value; }
        }

 

webservice .cs中

              [WebMethod(Description="1234567")]
        [SoapHeader("Credentails", Direction = SoapHeaderDirection.In)]
        [CredentialExtension]
        //[ScriptMethod(ResponseFormat=ResponseFormat.Json)]
        public DB.RSSItem[] GetArray()
        {
            //this.VerifyCredential(this);
            DB.RSSItem[] objs = ActiveRecordBase<DB.RSSItem>.SlicedFindAll(0, 5);
            foreach (RSSItem obj in objs)
            {
                obj.TClass = new TClass();
                //obj.TClass.Item = obj;//
            }
            return objs;//
        }

[WebMethod]
        public DB.RSSItem GetItem()
        {
            DB.RSSItem obj = GetArray()[0];// ActiveRecordBase<DB.RSSItem>.FindFirst();
            return obj;//
        }

 [WebMethod]
        [SoapHeader("Credentails", Direction = SoapHeaderDirection.In)]
        [CredentialExtension]
        //[GenerateScriptType(typeof(RSSItem))]
        //[GenerateScriptType(typeof(TClass))]
        public DB.RSSItem[] GetArray2(RSSItem obj)
        {
            return GetArray();
        }

 

用戶端 JS.aspx

         <script type="text/javascript" src="Content/script/jquery-1.2.6.pack.js"></script>   
    <script type="text/javascript" src="http://www.json.org/json2.js"></script>   
    <script language="javascript" type="text/javascript">     
//1、WebService請求類型都為Post,WebService的Url為“[WebServiceUrl]/[WebMethod]”
//2、contentType聲明為Json
//3、data要用Json的字串格式傳入
//4、設定了dataType為json後,result就直接為返回的Json對象。
var dd;
$(function()
{
    //調用無參數
    $("#btnHelloWorld").click(function(){
        $.ajax({
        type:"POST",
        contentType:"application/json",
        url:"WebServices/WebService1.asmx/GetItem",
        data:"{}",
        dataType:'json',
        success:function(result){
        dd=result.d;
        alert(result.d);
        }
        });
   
    });
   //傳入一個參數
   $("#btnHello").click(function(){
   var jsonStr = JSON.stringify(dd); //用Json2.js產生Json字串


   //jsonStr = jsonStr.replace(new RegExp('(^|[^////])//"/////Date//((-?[0-9]+)//)///////"', 'g'), "$1new Date($2)");//將“"//Date(ticks)//"”轉化為“new Date(ticks)


    //jsonStr = jsonStr.replace(new RegExp('(^|[^////])//"/Date//((-?[0-9]+)//)///"', 'g'), "$1new Date($2)");//將“"/Date(ticks)/"”轉化為“new Date(ticks)


    jsonStr = jsonStr.replace(new RegExp('(^|[^////])//"/Date//((-?[0-9]+)//)///"', 'g'), '$1/"///Date($2)////"');//將“"/Date(ticks)/"”轉化為“"//Date(ticks)//"”不然會出錯!!!
  //alert(jsonStr);
     $.ajax({
        type:"POST",
        contentType:"application/json",
       url:"WebServices/WebService1.asmx/GetArray2",
         //data:"{obj:99}",//
         data:"{obj:"+jsonStr+"}",//
        dataType:'json',
        success:function(result){
            alert(result.d);
        }
     });
   });

 

 

解決了傳GetArray2參數中傳自訂RSSItem類型的問題.....OK!!!

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.