AJAX JSON中日期类型DateTime格式化的序列化自定义对象以及自定义类型参数的问题处理

首先看一下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!!!

 

 

 

 

你可能感兴趣的:(JavaScript,json,Ajax,webservice,function,asp.net)