March 22, 2011

使用jQuery呼叫PageMethods

PageMethods功能的引入,允許使用者在Code-Behind中將方法公開出來讓Client端的Javascript可以非同步的方式呼叫Server端的程式,以下範例將介紹如何以jQuery來呼叫PageMethods,範例中將模擬使用者填寫會員註冊表單的情境。

首先,我們佈置了4個文字框及1個按鈕,如下
        姓:
        

        名:
                

        電話:
                

        住址:
                

        
接下來在Code-Behind中加入以下程式碼
        [WebMethod]
        public static ResponseDto RegisterUsingSingleParameter(JsonUser jsonUser)
        {
            RequestDto request = new RequestDto();
            request.FullName = string.Format("{0},{1}", jsonUser.Surname, jsonUser.GivenName);
            request.PhoneNumber = jsonUser.PhoneNumber;
            request.Address = jsonUser.Address;

            ResponseDto response = new UserService().AddUser(request);
            return response;
        }

        [WebMethod]
        public static string RegisterUsingMultipleParameters(string surname, string givenName, string phoneNumber, string address)
        {
            RequestDto request = new RequestDto();
            request.FullName = string.Format("{0},{1}", surname, givenName);
            request.PhoneNumber = phoneNumber;
            request.Address = address;

            ResponseDto response = new UserService().AddUser(request);
            return response.Message;
        }
以上的程式碼包含兩支Method,一個名稱為RegisterUsingSingleParameter,回傳型別為ResponseDto;而另一個名稱為RegisterUsingMultipleParameters,回傳型別為string。兩支Method做的工作其實是相同的,差別在於RegisterUsingMultipleParameters的參數被封裝在Data Transfer Object裡(JsonUser類別,為Client端傳遞過來反序列化後的物件)。

值得注意的是,欲公開出來的方法必須加上[WebMethod]屬性,並將方法宣告為static。這兩個方法皆使用Request-Response Pattern以Data Transfer Object(在此為RequestDto類別)傳遞使用者註冊資料至Service Layer的UserService類別,UserService類別會將使用者資料新增至資料庫,並把處理結果回傳至Presentation Layer

最後,撰寫Client端程式碼,使用jQuery呼叫Server端的PageMethods
<script language="javascript" src="http://code.jquery.com/jquery-1.5.1.min.js" type="text/javascript">
</script>
<script language="javascript" type="text/javascript">
        $(document).ready(function() {
            $("#btnRegister").click(function() {
                var data = {
                    'surname': $("#txtSurname").val(),
                    'givenName': $("#txtGivenName").val(),
                    'phoneNumber': $("#txtPhoneNumber").val(),
                    'address': $("#txtAddress").val()
                };

                $.ajax({
                    type: "POST",
                    url: 'Default.aspx/RegisterUsingMultipleParameters',
                    data: JSON.stringify(data),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function(result) {
                        alert(result.d);
                    },
                    error: function(jqXHR) {
                        var response = JSON.parse(jqXHR.responseText);
                        alert(response.Message);
                    }
                });
            });
        });
</script>

<script language="javascript" src="http://code.jquery.com/jquery-1.5.1.min.js" type="text/javascript">
</script>
<script language="javascript" type="text/javascript">
            $("#btnRegister").click(function() {
                var data = {
                    'jsonUser': {
                        'Surname': $("#txtSurname").val(),
                        'GivenName': $("#txtGivenName").val(),
                        'PhoneNumber': $("#txtPhoneNumber").val(),
                        'Address': $("#txtAddress").val()
                    }
                };

                $.ajax({
                    type: "POST",
                    url: 'Default.aspx/RegisterUsingSingleParameter',
                    data: JSON.stringify(data),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function(result) {
                        var response = result.d;
                        alert(response.Message);
                    },
                    error: function(jqXHR) {
                        var response = JSON.parse(jqXHR.responseText);
                        alert(response.Message);
                    }
                });
            });
</script>
有一點要特別注意的是,Client端變數data裡的屬性名稱需與Code-Behind中方法的參數名稱一致,否則無法呼叫的到該方法;而Default.aspx/Register後的Register即為Code-Behind中的方法名稱

以下為最終執行結果
新增成功


新增失敗


使用HttpWatch可以看出資料透過JSON於Client與Server間傳遞




範例程式下載

備註
為了方便,範例檔中將Service Layer以一資料夾Services放置在Web專案中。實務上,Service Layer會獨立為一個專案

延伸閱讀