.Net環境下基於Ajax的MVC方案

1、問題背景

現在,越來越多人開始嘗試基於Ajax進行無刷新的Web開發,不過,在.Net環境下,應用Ajax並不是非常方便,這主要可能是由以下一些原因造成的:

·由於Ajax基於javascript的本質,使得開發者必須對javascript非常瞭解,起碼,其javascript能力足以實現對callback返回內容對頁面的更新,所以開發的門檻就有一定程度的上升

·當基於Ajax機制進行開發時,原有的基於postback方式下時,asp.net由後臺邏輯代碼(Model),aspx頁面(View)、aspx.cs(Controller)構成的MVC構架其實失效了,當callback返回數據時,要麼在client端用javascript解析返回內容以實現更新,要麼則必須在server端構造好比較完整的html代碼,再直接由javascript將該構造好的html設置給某個頁面對象,很顯然,這樣一來,要實現一個最簡單的callback功能,都要不少代碼,並且是相對比較亂的代碼,即使在即將到來的asp.net2.0該問題依然不會得到有效解決

2、本文目的

本文旨在充分利於現有的asp.net本身的特點和ajax的特性,提出一個用於在asp.net環境下進行基於ajax的web開發的MVC方案,以實現以下主要目的:

·Asp.Net環境下用於Ajax的清晰的MVC構架

·降低編程人員對過多javascript編碼的依賴以降低編程門檻

·靈活的支持ajax模式下的常用開發方式

3、問題分析

如何實現以上幾個主要目的呢?

 1)要對xmlhttprequest對更良好的封裝,以使調用方式更簡單;

 2)儘量在server端進行更新數據的構造,但是也要避免每次返回數據都手工構造,因此,就想到可以充分使用UserControl,由UserControl作爲"View",對應的由ascx.cs文件作爲"Controller",這樣構成的MVC也是比較清晰的;
 
4、問題解決

基於以上思想,本人實現了以下一個組類庫以簡化該過程:

源碼及範例下載

代碼簡析:

1)首先在client端,AjaxHelper.js封裝了xmlhttprequest,並提供一個將現有的<form>序列化爲形如param1=v1&param2=v2&...形式用於post的參數;

Updater(ajaxTemplate, output, params, onComplete)函數,用於實現一次callback調用

ajaxTemplate(必選):指定執行需要功能的UserControl路徑
output(可選):填充返回數據的指定標籤的引用或ID值
params(可選):形如param1=v1&param2=v2&...的post參數
onComplete(可選):可用於對返回數據進行特殊處理的回調函數,函數格式function(str),str爲返回的數據

SerializeForm(form)函數,用於序列化<form>

form:可以是對指定<form>的引用或ID值

2)在server端,Ajax.aspx文件封裝了對由客戶端ajaxTemplate指定的UserControl的調用,其餘的具體邏輯功能則在特定的UserControl及其ascx.cs內實現;

3)這樣,具體執行一次callback時,編程人員只需在頁面引用AjaxHelper.js,並在指定的位置通過javascript:Updater(ajaxTemplate, output, params, onComplete)進行調用,如果需要對某一form進行提交,則可調用javascript:SerializeForm(form)序列化該form並傳給params,當然也可以手動構造params,並指定將返回數據通過設置output應用的頁面或通過onComplete自定義處理。

4)由於充分使用UserControl,意味着,可以充分利用asp.net原有的web服務器端控件和數據綁定機制,這樣其實,已經很大程度上簡化了返回數據的構造,在ascx.cs中,通過Request.Form[ParamName]就能訪問到client端傳入的params,再訪問邏輯代碼獲取源數據。

5、範例

包含在源碼中的範例實現了一個簡單的無刷新獲取博客園首頁內容到一個textarea的功能,詳見源碼!

部分範例源碼:

Default.aspx

<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="CN.Teddy.AjaxHelper.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
    
<HEAD>
        
<title>WebForm1</title>
        
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
        
<meta name="CODE_LANGUAGE" Content="C#">
        
<meta name="vs_defaultClientScript" content="JavaScript">
        
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
        
<script type="text/javascript" language="javascript" src="js/AjaxHelper.js"></script>
    
</HEAD>
    
<body>
        
<form id="Form1" method="post" runat="server">
            
<div id="view2">loading</div>
            
<script type="text/javascript">
                Updater('AjaxTemplate
/GetPageSrc', 'view2', 'url=http://www.cnblogs.com');
            
</script>

        
</form>
    
</body>
</HTML>


AjaxHelper.js摘要:

var AjaxHelperUrl = new String("Ajax.aspx");



var Updater = function(ajaxTemplate, output, params, onComplete)

{

    
if (typeof output == 'string')

    {

        output 
= $(output);

    }

    

    
new Ajax.Request( 'Ajax.aspx', { onComplete: function(transport) { if (output != null) { output.innerHTML = FormatContent(transport.responseText); } if (onComplete != null) { onComplete(FormatContent(transport.responseText)) } }, parameters: params + '&AjaxTemplate=+ ajaxTemplate });

}



var SerializeForm = function(form)

{

    
return Form.serialize(form);

}



var FormatContent = function(str)

{

    
var content = new String(str);

    
var prefix = new String("<!--AjaxContent-->");

    content 
= content.substring(content.indexOf(prefix, 0+ prefix.length, content.length - 9);

    
return content;

}


UserControl GetPageSrc.ascx.cs摘要:

        private void Page_Load(object sender, System.EventArgs e)
        
{
            lbUrl.Text 
= Request.Form["url"];

            System.Net.WebClient client 
= new System.Net.WebClient ();
            client.Headers.Add(
"User-Agent""Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)");
            
try
            
{
                txtPageSource.Text 
= new System.IO.StreamReader(client.OpenRead(lbUrl.Text), System.Text.Encoding.UTF8).ReadToEnd();
            }

            
catch(Exception ex)
            
{
                
throw ex;
            }

        }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章