一種開發模式:ajax + ashx + UserControl

1、ajax+ashx模式的缺點

    在web開發過程當中,爲了提升網站的用戶體驗,或多或少都會用到ajax技術,甚至有的網站所有采用ajax來實現,大量使用ajax在加強用戶體驗的同時會帶來一些負面影響,好比:不利於seo;然而,對於asp.net來講,通常會採用ashx文件做爲ajax調用的後臺,這種狀況下,每一個ajax請求都會對應一個ashx頁面,若是請求過多則會形成項目中有繁多的ashx文件,不利於管理與維護,那麼怎樣改善這種狀況呢?

2、問題分析與改進(反射)

    經過分析發現,每一個ajax調用ashx的步驟都是同樣,都分爲如下三步:
    一、解析請求中的用戶數據
    二、處理用戶請求
    三、返回處理結果
    這三個步驟中,第一和第三步對於每一個請求來講都同樣,只有第二部涉及到數據的具體處理,每一個請求會有所不一樣,所以須要針對第二個方面進行改進。
    ashx文件的類做爲一個Handler,它是繼承於IHttpHandler接口的,在處理業務時,每一個請求都會首先進入方法"ProcessRequest"中,爲了減小ashx文件的數量,咱們能夠將同一模塊中的操做放在一個ashx文件中進行處理,具體代碼相似下面中這樣:
    
public void ProcessRequest(HttpContext context)
    {
        // 一、解析請求參數,此處忽略
        // 二、如下爲具體處理方式
        string returnString = string.Empty;
        string methodName = context.Request.Form["methodName"];
        switch(methodName)
            case "GetData":
                returnString = GetData();
                break;
            case "InsertNewRow"
                returnString = InsertNewRow();
                break;
            .....等等多個case分支
            default:
            break;
        // 三、向客戶端返回結果        
        context.Response.Write(returnString);
    }

 

    這種方式經過在用戶請求中添加一個用來代表具體調用方法的參數,能夠將同一模塊中的操做所有放在一塊兒,並經過switch語句進行判斷,而後分別調用,這樣能夠減小必定數量的ashx文件。可是這種方式存在一個弊端,若是方法不少的話會形成switch語句出現大量的分支,而且每一個ashx文件中都須要在ProcessRequest方法中進行相同業務邏輯判斷,那麼怎樣將這些相同的行爲進行改進呢?咱們知道,請求中包含了須要調用的方法名,爲了將這些方法的調用進行統一處理,顯然咱們能夠利用反射。
    經過定義一個Handler基類,讓其餘全部的ashx類繼承此Handler,具體的處理方法寫在子類中,這樣基類的功能就能夠簡化爲以下形式:
    
//Handler基類中的方法,爲全部的Handler子類的方法進行調度
public void ProcessRequest(HttpContext context)
    {
        // 一、解析請求參數,此處忽略其餘參數的解析,僅獲取方法名
        string methodName = context.Request.Form["Action"];
        // 二、如下爲反射的具體處理方式
        Type type = this.GetType();
        Object[] params = new Objece[1];  //方法參數,咱們統一將context做爲參數,覺得用戶數據都封裝在其中
        MethodInfo method = type.GetMethod(methodName);
        string returnString = (string)method.Invoke(this,params);
        // 三、向客戶端返回結果        
        context.Response.Write(returnString);
    }

public String GetRequest(HttpContext context, String paramName)
{
    if (context.Request[paramName] != null)
    {
        return context.Request[paramName].ToString();
    }javascript

     return "";html

}java

 
  
 
而後,繼承該Handler的子類只須要實現具體的處理方法便可,該基類能夠統一爲全部子Handler進行方法調度,不再會出現可能會愈來愈臃腫的switch,該方式相似於mvc中的controller調度,經過action來進行判斷
    下面是一個子Handler的示例:
/// <summary>
    /// UserHandler 的摘要說明
    /// </summary>
    public class UserHandler : BaseHandler
    {
        /// <summary>
        /// 用戶登陸處理
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public String Login(HttpContext context)
        {
            String strAccount = "";
            String strPassword = "";
            String strRet;

            try
            {
                //獲取頁面傳值
                strAccount = GetRequest(context, "Account");
                strPassword = GetRequest(context, "Password");

                if (strAccount != "" && strPassword != "")
                {
                    //簡單起見,僅返回傳遞過來的用戶帳號與密碼
                    //在實際應用中利用傳遞過來的參數值調用業務邏輯層的方法來完成客戶端的請求
                    strRet = String.Format("帳號:{0},密碼:{1}", strAccount, strPassword);
                }
                else
                {
                    //返回提示信息
                    strRet = "未能正確獲取參數!";
                }


                return strRet;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        
    }

 

前臺調用代碼以下:
<script type="text/javascript">
        $(document).ready(function () {
            $("#btnLogin").click(function () {
                var account;
                var password;

                account = $("#txtUserName").val();
                password = $("#txtPassword").val();

                $.ajax({
                    type: "POST",
                    async: true,
                    url: "Handler/UserHandler.ashx",
                    dataType: "text",
                    data: { Action: "Login", Account: account, Password: password },
                    success: function (data) {
                        alert(data);
                    },
                    error: function (xhr) {
                        alert(xhr.statusText);
                        return false;
                    }
                });
            });
        });
    </script>

 


    至此,已經完成了ajax + ashx開發模式的改進,可是仍然存在一下兩個問題:
    一、由於採用了ajax技術,因此在提交請求時須要手動封裝表單中的數據,若是數據過多,封裝過程比較繁瑣
    二、在輸出時須要大量拼接html字符串,這也是一個繁瑣的活

3、ajax請求中表單數據的封裝

    爲了提升數據的封裝效率,咱們可使用jquery.form.js插件,該插件提供了便利的操做,能夠根據須要封裝表單中的所有或者部分數據,使用起來十分簡單。
,下面說一下UserControl的用法

4、利用UserControl進行html輸出

    在ajax+ashx處理方式中,大部分狀況下都須要進行html字符的拼接,這種拼接很是繁瑣卻又不得不作,若是是很是簡短的字符串還倒能夠,若是遇到大量數據的顯示,恐怕單單這一項任務就夠讓人煩的了,這裏咱們能夠利用用戶控件(UserControl)來幫咱們完成html的呈現,具體思路以下:
    定義一個視圖控制器類(ViewManage),專門用來建立用戶控件的實例和生成用戶控件的html,該試圖控制器內部主要經過定義一個空的Page類,而後將該用戶控件加載到Page中建立其實例,而後將Page對象的整個生命週期運行一遍,並將結果html輸出。
    經過用戶控件輸出html還不會影響頁面的SEO,由於在客戶端<a/>的href仍是有效的
 

總結:

該開發模式在利用ajax的同時,採用 "控制器+反射" 的模式進行方法調度,利用form插件來進行表單數據封裝,對於大數據量的輸出利用"用戶控件"進行html生成。
對於ajax與SEO,須要遵循如下幾點:
一、AJAX、SEO同等重要,在同一個WEB項目中爲他們各自選擇合適的使用領域。
二、會員管理、賬戶中心、購物車、後臺管理等操做界面可使用AJAX,以提升用戶體驗和UI交互。
三、網站前臺展現的頁面,如新聞內容、商品介紹、幫助、文檔類頁面,不要使用AJAX,以SEO爲主。
四、當咱們認清楚AJAX何時該用,何時不應用,一個網站的SEO與AJAX技術結合就變得很簡單了。
相關文章
相關標籤/搜索