2018年6月21日 星期四

Swashbuckle (3) 顯示 webapi 方法上 xml 的摘要

設定在 swagger 頁面顯示的 xml 摘要資訊

環境:vs2017、.net framework 4.7、Swashbuckle 5.6.0

首先建立好一個 WebApi 專案和透過 Nuget 裝好 Swashbuckle,並且透過
http://localhost:xxxxx/swagger 能夠進到 Swashbuckle 的頁面。

本篇的目的在於讓 Api 上面的 xml 註解中的資訊出現在 swagger 的頁面上

在安裝好 swashbuckle 後開啟 App_Start 中的 SwaggerConfig.cs,這個檔案
應該在 Nuget 安裝好 Swashbuckle 時就自動產生。

取消 SwaggerConfig.cs 中的下面這一行的註解

    c.IncludeXmlComments(GetXmlCommentsPath());

在同一個 Class ( public class SwaggerConfig ) 下增加方法

   
 internal static string GetXmlCommentsPath()
 {
   //透過設定專案的屬性,設定在建置後生成 XmlDocument.xml,
   //此處是設定 Swagger 參考這份 xml
   return string.Format(@"{0}\App_Data\XmlDocument.xml",
   System.AppDomain.CurrentDomain.BaseDirectory); 
 }

圖上刪了很多原本是註解掉的部份



設定專案屬性,右鍵點專案 > 專案屬性 > 建置頁籤 > 輸出

有一個 XML 文件檔案,勾選並設定檔案的路徑,這個路徑需要和前一步設定
的 XML 路徑對應。


WebApi 的例子
  
/// <summary>
/// 人員
/// </summary>
public class Person
{
    /// <summary>
    /// 人員名稱
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 人員年紀
    /// </summary>
    public int Age { get; set; }
}

/// <summary>
/// 錯誤狀態
/// </summary>
public class ErrorStatus
{
    /// <summary>
    /// 狀態代碼
    /// </summary>
    public string StatusCode { get; set; }
    /// <summary>
    /// 狀態描述
    /// </summary>
    public string Description { get; set; }
}

 
public class PeopleController : ApiController
{
   /// <summary>
   /// 取得人員資料
   /// </summary>
   /// <remarks>
   /// 取得人員資料 api 的補充說明
   /// </remarks>
   /// <param name="id">人員 Id</param>
   /// <response code="200">成功</response>
   /// <response code="404">找不到</response>
   /// <response code="500">內部伺服器錯誤</response>
   [ResponseType(typeof(Person))]
   public IHttpActionResult Get(string id)
   {
      return Ok(new Person());
   }
}

如果設定了 [ResponseType(typeof(Person))] 因為他預設是在 Http Status 200
的時候所回傳的類別,所以需要同時設定 <response code="200">成功</response>
才會正常顯示 [ResponseType(typeof(Person))] 的部份

在傳入值或回傳值,切換到 Model 下時會顯示定義在 DataModel 上的 <summary> 訊息

執行專案,然後接下來進到 Swagger 頁面就可以看到 webapi 上設定的 xml 註解的資訊


在比較新版的 Swashbuckle 中,可以利用 SwaggerResponse 這個 attribute 來取代
<response code=""></response>

 
public class PeopleController : ApiController
{
  /// <summary>
  /// 取得人員資料
  /// </summary>
  /// <remarks>
  /// 取得人員資料 api 的補充說明
  /// </remarks>
  /// <param name="id">人員 Id</param>
  [SwaggerResponse(HttpStatusCode.OK, Description = "成功", Type = typeof(Person))]
  [SwaggerResponse(HttpStatusCode.NotFound, Description = "找不到")]
  [SwaggerResponse(HttpStatusCode.InternalServerError, Description = "內部伺服器錯誤", Type = typeof(ErrorStatus))]
  [ResponseType(typeof(Person))]
  public IHttpActionResult Get(string id)
  {
    return Ok(new Person());
  }
}


2018年6月20日 星期三

Swashbuckle (1) 基本使用

環境:vs2017、.net framework 4.7、Swashbuckle 5.6.0

Swashbuckle,其實就是 Swagger,基本上是一套產生線上 API
文件的產生器,線上文件(網頁)同時也可以產生一個呼叫 API 的頁面。

在實際使用上有很多不同的進階選項可以使用,本篇只說明最基礎的部份。

建立一個 WebApi 專案,在專案中建立 PeopleController

    PeopleController.cs

public class PeopleController : ApiController
{
    /// <summary>
    /// 取得人員資料
    /// </summary>
    /// <returns></returns>
    public string Get(string id)
    {
        return ("Ricky");
    }
    /// <summary>
    /// 新增人員資料
    /// </summary>
    /// <returns></returns>
    public HttpResponseMessage Post(Person person)
    {
        return Request.CreateResponse(
            HttpStatusCode.Created, new { Status = "OK" });
    }
}


public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

透過 Nuget 安裝套件 Swashbuckle 和 Swashbuckle.Core Swashbuckle 相依於 Swashbuckle.Core 所以實際上裝 Swashbuckle 另 一個會自已裝好。
安裝好後直接執行專案

然後網址輸入 http://localhost:xxxxx/swagger,就能開啟 WebApi 文件的介面



輸入好參數(如果該 api 需要),點下面的 try out 就能呼叫 api

以上就是最基本的使用部份,Swashbuckle 依照 Api Controlle 中的基本資訊
(ex. 參數、回傳值)等,生成頁面上的資訊,但諸如方法上的 <summary> 註解
等都不會反應到頁面上。

Swashbuckle (2) 利用設定 ResponseType 告知 swagger 實際上回傳的型別為何

當 api 回傳的型別是 IHttpActionResult 時,利用設定 ResponseType
告知 swagger 實際上回傳的型別為何。

環境:vs2017、.net framework 4.7、Swashbuckle 5.6.0

透過 ResponseType 屬性,控制 Swagger 頁面所顯示的資訊

WebApi 的內容

//ResponseType 的 namespace 是 System.Web.Http.Description

using System.Web.Http.Description;

public class ValuesController : ApiController {
  [ResponseType(typeof(Person))]
  public IHttpActionResult Get(string id)
  {
    return Ok(new Person());
  }
}

加上 [ResponseType(typeof(Person))] 前後的比對,可以透過 Model 和 Example Value 的切換
切換樣本和回傳的 Model 的定義。



2018年6月12日 星期二

[Visual Studio] 同時輸出到不同的目標 Framework

建立一個 .NET Standard 類型的專案


在專案上點右鍵選「編輯 xxx .csproj」,就是編輯那個專案檔,因為是 .NET Standard 類型
的專案,所以不用先缷載專案。


將 .csproj 檔中的

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

修改成如下,要注意的是 「TargetFramework」修改後「TargetFrameworks」
和裡面的「net45;netstandard1.1」,指的是要產生.net framework 4.5 及
.net standard 1.1 為目標編譯出的類別庫

<PropertyGroup>
<TargetFrameworks>net45;netstandard1.1</TargetFrameworks>
</PropertyGroup>

接下來存檔之後應該會跳訊息要重新載入專案,重新載入即可,在載入完成後可
以在專案的相依性上看到 .NETFramework 4.5 和 .NETStandard 1.1 兩個項目


之後建置專案之後,就可以在專案的 Debug 或 Release 資料夾下看到 net45 和
netstandard1.1 兩個資料夾,裡面就是各自編譯出來的類別庫。



2018年6月9日 星期六

[jQuery] validate.unobtrusive 驗證(3) 自訂驗證

jquery.validate、jquery.validate.unobtrusive 自訂驗證

基本

    $.validator.addMethod 和 $.validator.unobtrusive.adapters.add
    需要在載入 DOM 之前就先執行

下面的例子包括

    不額外傳入驗證條件
    傳入一個驗證條件
    傳入多個驗證條件

不額外傳入驗證條件(ex.自定用來比對的上限/下限值)的例子,本例中假設
欄位字元長度不能超過5

validator.addMethod() 裡的 stringlengthcheck 對應到 html tag 裡的 data-val-stringlengthcheck
<head>
    <script>
        //stringlengthcheck 是在 html tag 中對應的 data-val-stringlengthcheck
        $.validator.addMethod('stringlengthcheck', function (value, element, params) {
            //假設驗證欄位不可大於5
            return value.length <= 5;
        });
        //因為沒有要多傳參數做判斷,所以在 adapters.add 中沒有特別處理
        //為了要做 unobtrusive 的設定
        $.validator.unobtrusive.adapters.add("stringlengthcheck", function (options) {
            options.rules["stringlengthcheck"] = {
            };
            options.messages["stringlengthcheck"] = options.message;
        });
    </script>        
</head>
<body>
    <input type="text" value="" name="money" id="money" data-val="true" data-val-stringlengthcheck="字元長度限制" />
    <span data-valmsg-for="money" data-valmsg-replace="true"></span>            
</body>
傳入一個驗證條件
<head>
    <script>
        //傳入一個額外驗證條件
        //data-val-stringlengthcheck="錯誤訊息" 會觸發驗證
        //$.validator.addMethod 的 stringlengthcheck 要對應到 html tag 的 data-val-stringlengthcheck
        $.validator.addMethod('stringlengthcheck', function (value, element, params)
        {
            //驗證條件,欄位內容長度需要小於
            return value.length <= params["myMaxValue"];
        });
        //$.validator.unobtrusive.adapters.add 的 ["myMaxValue"] 對應到 html tag 的 data-val-stringlengthcheck-myMaxValue
        $.validator.unobtrusive.adapters.add("stringlengthcheck", ["myMaxValue"], function (options)
        {
            //要指定參數,在 validator 裡才接的到
            options.rules["stringlengthcheck"] = {
                myMaxValue: options.params.myMaxValue
            };
            options.messages["stringlengthcheck"] = options.message;
        });
    </script>
</head>
<body>
    <input type="text" name="myValue1" id="myValue1" 
        data-val="true" 
        data-val-stringlengthcheck="超過上限" 
        data-val-stringlengthcheck-myMaxValue=10 />
    <span data-valmsg-for="myValue1" data-valmsg-replace="true"></span>
</body>
傳入多個驗證條件
<head>
    <script>
        $.validator.addMethod('stringlengthcheck', function (value, element, params)
        {
            return value.length >= params["myValue1"] && value.length <= params["myValue2"];
        });
        //參數用 ["myValue1","myValue2"] 對應到 html tag 就是 
        //data-val-stringlengthcheck-myValue1 和 data-val-stringlengthcheck-myValue2
        $.validator.unobtrusive.adapters.add("stringlengthcheck", ["myValue1","myValue2"], function (options)
        {
            var params ={
                myValue1: options.params.myValue1,
                myValue2: options.params.myValue2
            }
            options.rules["stringlengthcheck"] = params;
            options.messages["stringlengthcheck"] = options.message;
        });        
    </script>
</head>
<body>
    <input type="text" value="" name="myValue" id="myValue" data-val="true" 
        data-val-stringlengthcheck="超過上下限"
        data-val-stringlengthcheck-myValue1=1
        data-val-stringlengthcheck-myValue2=2 />
    <span data-valmsg-for="myValue" data-valmsg-replace="true"></span>
</body>

[jQuery] validate.unobtrusive 驗證(2) 透過 Ajax (data-val-remote) 方式呼叫後端驗證

jquery.validate、jquery.validate.unobtrusive 透過 Ajax (data-val-remote) 方式呼叫後端驗證

省略部份程式碼,基本用法請參考另一篇文章

基本用法
    <body>
        <head>
            <script src="Scripts\jquery-1.10.2.js"></script>
            <script src="Scripts\jquery.validate.js"></script>
            <script src="Scripts\jquery.validate.unobtrusive.js"></script>
        </head>
        <form id="form1" method="get">

            <!-- data-val-remote 檢核失敗的訊息 -->
            <!-- data-val-remote-url 檢核網頁程式的網址 -->
            <!-- data-val-remote-type 設定 GET 或 POST -->
            <!-- data-val-remote-additionfields 要額外多傳的欄位名稱,可用","分隔指定多欄,沒有就不用給 -->

            <input type="text" name="loginName" data-val="true" 
                data-val-remote="後端回傳false時頁面上要呈現的訊息" 
                data-val-remote-url="http://localhost:14630/api/values"
                data-val-remote-type="GET" />
            <span data-valmsg-for="loginName" data-valmsg-replace="true"></span>

        </form>
    </body>

回傳的結果只能是 true/false

當指定 data-val-remote-type 為 GET 時,欄位的資料會被當作 QueryString 傳遞

只會在設定 data-val-remote 的欄位變動或 Send 時才會呼叫後端,所以當驗證需要回傳
多個欄位,而且不是每個欄位都設定 data-val-remote 的情況下,部份欄位的異動可能不
會再進行後端的檢查(因為沒設定 data-val-remote)。

以下展示呼叫及回傳的前後端程式碼

前端用 GET 呼叫後端 ASP.NET WebApi 傳遞一個參數
前端用 GET 呼叫後端 ASP.NET WebApi 傳遞三個參數
前端用 GET 呼叫後端 ASP.NET MVC 傳遞一個參數
前端用 GET 呼叫後端 ASP.NET MVC 傳遞三個參數
前端用 POST 呼叫後端 ASP.NET WebApi
前端用 POST 呼叫後端 ASP.NET MVC

前端用 GET 呼叫後端 ASP.NET WebApi 傳遞一個參數

前端
<!-- 會以如下的 uri 呼叫後端 http://localhost:12345/api/values?loginName=ABC -->

<input type="text" name="loginName" data-val="true" 
       data-val-remote="資料已存在!" 
       data-val-remote-url="http://localhost:14630/api/values"
       data-val-remote-type="GET" />
<span data-valmsg-for="loginName" data-valmsg-replace="true"></span>
後端
namespace WebApplication7.Controllers
{
    public class ValuesController : ApiController
    {
        public IHttpActionResult Get(string loginName)
        {
            bool f = true;

            if(loginName == "ABC")
            {
                f = false;
            }
            return Json<bool>(f);
         }
     }
 }

前端用 GET 呼叫後端 ASP.NET WebApi 傳遞三個參數
前端在指定 data-val-remote-additionalfields 要額外傳那些欄位時,指定的是 tag 的 name

前端
<!-- 會以如下的 uri 呼叫後端  http://localhost:12345/api/values?loginName=ab&Tel=b&Address=c -->

<input type="text" name="loginName" data-val="true" 
       data-val-remote="資料已存在!" data-val-remote-url="http://localhost:14630/api/values"
       data-val-remote-type="GET" 
       data-val-remote-additionalfields ="Tel,Address" />
<input type="text" id="idTel" name="Tel" />

<input type="text" id="idAddress" name="Address" />

<span data-valmsg-for="loginName" data-valmsg-replace="true"></span> 
後端
namespace WebApplication7.Controllers
{
    public class ValuesController : ApiController
    {
        public IHttpActionResult Get(string loginName, string Tel, string Address)
        {
            //略
            return Json<bool>(false);
        }
    }
}

前端用 GET 呼叫後端 ASP.NET MVC 傳遞一個參數

前端
<input type="text" name="loginName" data-val="true" 
    data-val-remote="資料已存在!" 
    data-val-remote-url="http://localhost:14630/home/Index"
    data-val-remote-type="GET" 
/>
<span data-valmsg-for="loginName" data-valmsg-replace="true"></span>
後端
[HttpGet]
public ActionResult Index(string loginName)
{
    //驗證
    bool b = false;
    return Json(b, JsonRequestBehavior.AllowGet);
}

前端用 GET 呼叫後端 ASP.NET MVC 傳遞三個參數

前端
<input type="text" name="loginName" 
    data-val="true" data-val-remote="資料已存在!" 
    data-val-remote-url="http://localhost:14630/home/Index"
    data-val-remote-type="GET" 
    data-val-remote-additionalfields ="Tel,Address"        
/>
<input type="text" id="idTel" name="Tel" />
<input type="text" id="idAddress" name="Address" />
<span data-valmsg-for="loginName" data-valmsg-replace="true"></span>
後端
[HttpGet]
public ActionResult Index(string loginName, string Tel, string Address)
{
    return Json(false, JsonRequestBehavior.AllowGet);
}

前端用 POST 呼叫後端 ASP.NET WebApi
使用 POST 的時候,欄位傳遞的資訊會在 POST Body 中傳遞,所以基本上後端繫結
到參數時,都要以物件去繫結。

前端
<input type="text" name="loginName"
    data-val="true" data-val-remote="資料已存在!" 
    data-val-remote-url="http://localhost:14630/api/values"
    data-val-remote-type="POST"         
    data-val-remote-additionalfields ="Tel,Address"        
/>
<input type="text" id="idTel" name="Tel" />
<input type="text" id="idAddress" name="Address" />
<span data-valmsg-for="loginName" data-valmsg-replace="true"></span>   
後端
//自訂 Class
public class UserInfo
{
    public string loginName { get; set; }
    public string Tel { get; set; }
    public string Address { get; set; }
}
public IHttpActionResult Post(UserInfo t)
{
    //驗證
    return Json<bool>(false);
}

前端用 POST 呼叫後端 ASP.NET MVC

前端
<input type="text" name="loginName" 
    data-val="true" data-val-remote="資料已存在!" 
    data-val-remote-url="http://localhost:14630/home/Index"
    data-val-remote-type="POST"         
    data-val-remote-additionalfields ="Tel,Address"        
/>
<input type="text" id="idTel" name="Tel" />
<input type="text" id="idAddress" name="Address" />
<span data-valmsg-for="loginName" data-valmsg-replace="true"></span>    
後端
//自訂 Class
public class UserInfo
{
    public string loginName { get; set; }
    public string Tel { get; set; }
    public string Address { get; set; }
}

[HttpPost]
public ActionResult Index(UserInfo ui)
{
    return Json(false);
}

2018年6月7日 星期四

[jQuery] validate.unobtrusive 驗證(1) 基本用法

環境,在 vs2013 中建立 mvc 預設專案 (就是會有預設的頁面的那種),再將其中的幾個
js 檔取出來做測試

jquery.validate 加上 validate.unobtrusive 基本上就是達成以 unobtrusive 的方
式對頁面上的欄位進行驗證。

因為是以 unobtrusive 進行,所以如何去設定欄位如何去驗證這件事情,就由原本放在
onclick 或 blur 之類的事件中,去指定並取得欄位值的方式,轉而改用設定屬性指定
要是否要驗證及驗證方式。

在使用上,有分幾個方向 (本篇是第一種)

    第一種就是只對單一欄位,以內建預設的基本檢核,比方說欄位不可為空,Email 格
    式是否正確這種。

    第二種稍微複雜一點,需要再另行決定一些「資訊」比方說,檢查欄位的值是否在某個
    區間中,這個區間就是必須要自行決定的範圍,或是需要透過正則表達式檢查欄位。

    第三種是透過 Ajax 呼叫後端進行檢查

    第四種則是自定驗證。

基本的使用

<html>
        <head>
            <script src="Scripts\jquery-1.10.2.js"></script>
            <script src="Scripts\jquery.validate.js"></script>
            <script src="Scripts\jquery.validate.unobtrusive.js"></script>
        </head>
        <body>
            <form id="form1" method="get">

                <!-- 透過設定 data-val="true" 表示要進行驗證該 tag -->
                <!-- 透過設定 data-val-required="欄位不可為空" 表示要以該欄位不可為空的條件驗證該欄位,並當檢核失敗時顯示錯誤訊息「欄位不可為空!」 -->
                <input type="text" name="username" id="username" data-val="true" data-val-required="欄位不可為空!" />

                <!-- 下面的 tag 會顯示 name 屬性為 username 的 tag 進行驗證時所產生的錯誤訊息 -->
                <!-- data-valmsg-for 是對應到受驗證欄位的 name -->
                <!-- data-valmsg-replace 為必要 (有試過有些版本的驗證不用) -->
                <span data-valmsg-for="username" data-valmsg-replace="true"></span>

                <!-- 下面的 tag 會將頁面上驗證的錯誤訊息都集中在這 -->
                <div class="validation-summary-valid" data-valmsg-summary="true">
                    <ul>
                        <li style="display: none"></li>
                    </ul>
                </div>

                <input type="submit" id="send" value="Send" />            
            </form>
        </body>
    </html>
欄位不可為空
<!-- data-val-required="欄位不能为空!" -->
<input type="text" name="uid" id="uid" data-val="true" data-val-required="欄位不能为空!" />
<span data-valmsg-for="uid" data-valmsg-replace="true"></span>

檢查 Email 格式
<!-- data-val-email="Email不正確" -->
<input type="text" name="email" id="email" data-val="true" 
       data-val-required="Email 不能為空" data-val-email="Email不正確" />
<span data-valmsg-for="email" data-valmsg-replace="true"></span>

檢查 url 格式
<!-- data-val-url="網址錯誤" -->
<input type="text" name="url" id="url" data-val="true"
       data-val-url="網址錯誤">
<span data-valmsg-for="url" data-valmsg-replace="true"></span>

日期驗證有一套規則,我是覺的不太好用,或許用自定驗證來處理會比較恰當
<!-- data-val-date="日期錯誤" -->
<input type="text" name="ndate" id="ndate" data-val="true" value=""
       data-val-date="日期錯誤">                
<span data-valmsg-for="ndate" data-valmsg-replace="true"></span>

正整數
<!-- data-val-digits="必須輸入正整數" -->
<input type="text" name="digits" id="digits" data-val="true"
       data-val-digits="必須輸入正整數">
<span data-valmsg-for="digits" data-valmsg-replace="true"></span>

檢查所輸入的是否為數字,小數可以、負數可以、整數可以
<!-- data-val-number="必須為有效數字" -->
<input type="text" name="number" id="number" data-val="true"
       data-val-number="必須為有效數字">
<span data-valmsg-for="number" data-valmsg-replace="true"></span>

比對兩個欄位的內容是否一致
 <!-- data-val-equalto 指定欄位不一致時的錯誤訊息 -->
 <!-- data-val-equalto-other 要比對的另一個欄位的 name 屬性 -->
 <body>
    <form id="form1" method="get">
        <input type="password" name="pwd" id="pwd" data-val="true" />
        <input type="password" name="pwd2" id="pwd2" data-val="true" 
               data-val-equalto="兩次輸入的密碼不一致。" data-val-equalto-other="pwd"
        />
        <span data-valmsg-for="pwd2" data-valmsg-replace="true"></span>
        <input type="submit" id="send" value="Send" />            
    </form>
</body>

檢查欄位內容的長度
在 data-val-length-max 和 data-val-length-min 間輸入欄位長度的上下限,如果沒有這
個屬性,就表示長度沒有上/下限,data-val-length 則是表示這個欄位需要檢查長度,
並且設定當欄位長度錯誤時要回應什麼錯誤訊息。
<!-- data-val-length-max="10" data-val-length-min="6" -->
    <!-- data-val-length="欄位長度需要在 6 ~ 10 個字元間" -->
    <body>
        <form id="form1" method="get">
            <input type="text" name="columnLength" id="columnLength" data-val="true" 
                data-val-length-max="10" data-val-length-min="6"
                data-val-length="欄位長度需要在 6 ~ 10 個字元間" />
            <span data-valmsg-for="columnLength" data-valmsg-replace="true"></span>
            <input type="submit" id="send" value="Send" />            
        </form>
    </body>    

2018年6月5日 星期二

[jQuery]利用 jQuery.ajax 讀取 Json 檔案

利用 jQuery.ajax 讀取 Json 檔案

環境:vs2017、asp.net mvc、jquery-1.10.2.js (專案建立時預設)

以下的範例是透過 vs2017 建立 asp.net mvc 專案 (有預設頁面的那種),建立
之後。

1.先在專案中增加 Json 資料夾
2.再修改 Home/Index.cshtml 的內容而成

使用到的 Json 檔則是放在 Json 資料夾中

testdata.json

{
    "Key1":"Value1",
    "Key2":"Value2"
}

然後在 Views\Web.config 中增加新的 mime,如果站台是架在 IIS 上,可以考慮設
定在 IIS 的 mime 上。

<system.webServer>
    <staticContent>
        <mimeMap fileExtension=".json" mimeType="application/json">
    </staticContent>
</system.webServer>

最後是頁面上寫讀取 Json 的 ajax

注意要用 GET

\Home\Index.cshtml

@{
 Layout = null;
}

<html>
<head>
 <title></title>
 <script src="~/Scripts/jquery-1.10.2.min.js"></script>
 <script>
  jQuery.ajax({
   url: '/Json/testdata.json',
   type: 'GET',
   success: function (response) {
    alert(JSON.stringify(response));
    alert(response.Key1);
    alert(response.Key2);
   }
  })
  //或是透過 jQuery.getJSON 取得 json
  jQuery.getJSON('/Json/testdata.json',
   function (data) {
    alert(JSON.stringify(data));
    alert(data.Key1);
    alert(data.Key2);
   });
 </script>
</head>
<body>
</body>
</html>