2016/07/01

[C#] 在 WebForm 中透過 WebMethod,提供 jQuery Ajax 非同步功能

過去寫程式遇到問題,最直覺的方式就是找 Google 大神。不過久了發現,有些問題總是一而在、再而三的重複出現。雖然對先前的解決方式總有印象,但還是得耗費許多時間一一從 Google 大神找出的資料中一一篩選解答。另外,雖然還有 Evernote 這個獨角獸可用,但每次把資料擷取下來後,需要時還是得花時間一一篩選。看來,還是自己消化後,寫篇文章會比較有印象吧。

前一陣子主要利用 MVC 開發系統。而最近接手的案子因為沒什麼時間改寫,因此還是重回傳統 Web Form 的方式撰寫。最近發現有個透過前端 jQuery 呼叫後台方法的需求。這方法在 MVC 開發中非常方便 (Controller 回傳 JsonResult 即可),但換到 Web Form 中卻一時困住了。此時才發現:只要將方法標示為 WebMethod,幾乎也可滿足我要的需求。

不過,實際開發後,才發現 Web Form 的開發方式需要注意的地方實在太多了。以下就來記錄一下。

WebForm 寫法:

  1. 先在 Code behind 中建立一個 Web Method,並指定為
    [WebMethod]
    (行 17)。由於預設中不會載入
    System.Web.Services
    ,因此要手動加入。
  2. 需要注意的是:WebMethod 的 function 一定要指定為
    static
  3. 接著,處理一些要做的事情,並建立要回傳的 JSON 字串
  4. 行 20,在回傳 JSON 時,我使用 Json.NET 來序列化字串。其實也可以用 .NET 內建的方法,不過 Json.NET 的方法很直覺,個人比較推。不過記得使用前要載入 Newtonsoft.Json (可至 Nuget 安裝,指令:
    Install-Package Newtonsoft.Json)

//WebMethodTest.aspx.cs
//Code-Behind

using Newtonsoft.Json;
using System;
using System.Web.Services;

namespace ESH_LOMS
{
    public partial class WebMethodTest : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        [WebMethod]
        public static string ajax_test(int? id, Boolean is_test, string cmd = "")
        {
            var result = new { id = id.Value, cmd = cmd, is_test=is_test};
            return JsonConvert.SerializeObject(result);
        }
    }
}
在 View 的地方 (我忘了 WebForm 怎麼稱呼,MVC 寫習慣了,就都叫他 View 吧),主要是處理 JQuery 的地方。主要注意的點有:
  1. 行 4 直接指定 WebMethod 的位置
  2. 行 5 的
    data
    變數中,指定要傳送給
    ajax_test
    方法的參數。重點是:直接傳一整組字串
  3. WebMethod 會直接將結果回傳給 行 8 的
    response
    字串。此時型態為 Object。若需拆解回傳的單一屬性,須將回傳字串先行 Parse 過,這樣才能使用類似
    obj.id
    方式取得單一屬性。
$(function() {
    $.ajax({
        type: "POST",
        url: "http://localhost/WebMethodTest.aspx/ajax_test",
        data: "{is_test:true, id: 1, cmd:'test'}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(response) {
            var obj = JSON.parse(response.d);
            alert(obj.id + ", " + obj.cmd + ", " + obj.is_test);
        }
    });
});


MVC 寫法

至於 MVC 的寫法就簡單許多了。只要在  Controller 中建立回傳 JsonResult 類型的 Action 即可,免除建立 Json 字串後須序列化這道手續。
//Controller
public JsonResult ajax_test(int? id, Boolean is_test, string cmd = "")
{
  return Json(new
  {
    id = id.Value,
    cmd = cmd,
    is_test = is_test
  });
}

而 View 的地方,基本上跟 WebForm 一樣。不過為了更方便利用回傳的 Json 內容,在 $.ajax 中進行一些小動作 (參閱: 黑大《【答客問】使用jQuery.ajax傳送複雜參數到ASP.NET MVC》:
//View
(function($) {
    //包裝一下 jQuery $.ajax 的呼叫方式
    $.extend($, {
        //=========== Replace item[0][propName] to item[0].propName for MVC model binder ===========
        postMvc: function(url, data, succ, dataType) {
            return $.ajax({
                url: url,
                type: "POST",
                dataType: dataType,
                data: data,
                success: succ,
                traditional: true,
                beforeSend: function(xhr, settings) {
                    settings.data = settings.data.replace(/%5D%5B(.+?)%5D=/g, "%5D.$1=");
                }
            });
        }
    });
})(jQuery);

$(function() {        
    $.postMvc(
        '@Url.Action("ajax_test")',
        {
            id : 1,
            is_test : true
            cmd = 'Test'
        },
        function(data) {
            alert(data.id + ", " + data.cmd + ", " + data.is_test);
        },
        'json');
});



沒有留言 :

張貼留言

注意:只有此網誌的成員可以留言。