2013-05-14 79 views
1

我有一個運行在ASP.Net下的網站。它有一些ascx控件,每個控件都代表不同的頁面。母版頁將在ascx上調用LoadControl(),然後將其添加到面板。然後,ascx Page_Load()會將個人保存功能掛接到頁面上的事件,以便母版頁上的「保存」按鈕可以做正確的事情。這一切都工作。對jQuery動態添加的ASP.Net控件執行回發

我現在正在努力變得更加動態,並更多地使用jQuery,並在客戶端做更多的事情。爲此,我正在嘗試動態加載ascx控件。我們的目標是能夠對每個ascx進行最小限度的更改。我有一個頁面,其內容如下(編輯爲了簡潔):當用戶點擊一個標籤上

<head> 
<script language="javascript" type="text/javascript"> 
function documentMetadataLoad() 
{ 
    jQuery.ajax({ 
     type: "GET", //GET 
     url: "JQueryHandler.ashx?Operation=LoadPage&Name=/UserControls/DocumentManagment/DocumentMetadata.ascx", 
     dataType: "html", 
     cache: false, 
     success: function (response) 
     { 
     $('#property_tab').html(response); 
     }, 
     error: function() 
     { 
     debugger; 
     $('#property_tab').html('error'); 
     } 
    }); 
</script> 
</head> 
<body id="mainBody" class="bodyClass"> 
<form id="form1" runat="server"> 
<div id="btn_save"> 
    <a href="#" id="btnSave" class="topBtnText">Save</a> 
</div> 
<div> 
    <div id="tab1" onclick="documentMetadataLoad(); ">Properties</div> 
</div> 
<div id="property_tab" style="display: Block;"></div> 
</form> 
</body> 

此頁面將動態加載稱爲DocumentMetadata.ascx控制。 (是的,我知道客戶端通過控制路徑時可能存在一個嚴重的安全漏洞,但這是一個概念驗證。)

JQueryHandler將採用給定的路徑並生成一個頁面。它ProcessRequest()看起來是這樣的:

public void ProcessRequest(HttpContext context) 
{ 
    if (context.Request.QueryString["Operation"] == "LoadPage") 
    { 
     String strPath = context.Request.QueryString["Name"]; 
     using (TisPage MyPage = new TisPage()) 
     { 
      HtmlForm f = new HtmlForm(); 
      f.Action = context.Request.UrlReferrer.AbsolutePath; 
      UserControl userctrl = MyPage.LoadControl(strPath) as UserControl; 
      f.Controls.Add(userctrl); 
      MyPage.Controls.Add(f); 
      context.Server.Execute(MyPage, context.Response.Output, true); 
     } 
    } 
} 

(謝謝http://www.infoconcepts.com/rendering-ascx-files-ajax/用於指示HtmlForm控件換行控制)TisPage是System.Web.UI.Page的子類,以保存數據的添加事件, ascx期望。

現在,我遇到的問題是我希望DocumentMetadata.ascx在用戶按下#btnSave時調用其保存函數。這是背後的代碼,它期望保留它的視圖狀態。所以我認爲我必須有回傳。我不想用傳入的參數來重寫C#保存函數作爲它自己的ashx調用;有很多這樣的頁面,重寫它們都是不值得的。

我在DocumentMetadata.ascx中有以下代碼來設置按鈕按下來執行某些操作。

$(document).ready(function() 
{ 
    $("#btnSave").bind("click", Save); 

}); 

function Save() 
{ 
    debugger; 
    __doPostBack('ctl00', null); 
} 

我嘗試由具有在Javascript來__doPostBack()一個電話,但後來我得到的錯誤:「視圖狀態MAC驗證失敗如果此應用程序由網絡場或羣集承載,請確保配置指定了相同的validationKey和驗證算法,AutoGenerate不能在集羣中使用。「作爲一個實驗,我試圖從我的web.config中刪除我的機器密鑰配置,但這似乎沒有幫助。

有沒有一種方法可以使用JavaScript來調用jQuery加載的ascx控件背後的代碼?

+1

您不能使用通過ajax加載的控件的回發方法。我建議將所有這些回發方法轉換爲類並使用Web服務/方法與它們進行通信。這需要一些時間,但從長遠來看,您將擁有更清潔/更快速/多功能的應用程序。 – 2013-05-14 18:33:17

+0

我同意,如果代碼被轉移到Web服務中,一切都會變得更好,但是頁面數量太多卻讓人望而卻步。解決方法是繼續爲這些頁面使用舊界面,但對新頁面使用jQuery Ajax方法。 你有一個引用,指出回發不能在ajax加載控件中使用嗎?我希望能夠向我的老闆展示一份正式聲明。 – 2013-05-14 22:23:17

回答

2

通過ajax加載.ascx控件與加載字符串相同。這是一種單向管道,並且該控制器沒有後置通信。 UpdatePanel解決方案也不起作用(並且它們也是可怕的)。

我的建議是使用諸如小鬍子之類的東西創建客戶端模板。js,然後通過ajax加載JSON數據以填充這些模板,以及使用web服務與您的服務器/數據庫進行通信的ajax。通過分離你的代碼,它會更容易維護,你將能夠重用更多的代碼,更好的效率等。

後備是老派技術,UpdatePanels只是ajax的一個討厭的實現。花一些時間,爲你的應用程序和你自己做正確的事情,你會因此而變得更好。

+0

這很不幸聽到,但現在我可以停止浪費我的時間。我所擁有的ascx頁面幾乎完全在jQuery中完成,因爲它爲所有數據使用Web服務。展望未來,我們將使用該方法,但舊頁面可能永遠不會被轉換。感謝您的信息。 – 2013-05-15 21:44:23

0

如果您使用UpdatePanel,則可以更輕鬆地完成您在此處的操作。它在客戶端使用部分回發,並保留ASP頁面生命週期。 您可以使用UpdatePanel封裝您的#property_tab和您的#btnSave並管理回發事件服務器端。

+0

我在'#property_tab'和'#btnSave'周圍增加了'UpdatePanel',並且我仍然得到「視圖狀態MAC驗證失敗。」錯誤。作爲一個實驗,爲了測試@BradM評論,我在DocumentMetadata.ascx上添加了一個按鈕,以查看它在按下時發生了什麼並導致了回發。我收到了同樣的錯誤。 – 2013-05-14 21:53:51

+0

@ErikAllen使用updatepanels,您需要將您使用服務器端代碼編寫的JavaScript代替。這裏的問題是,當您通過Ajax加載控件時,其服務器端事件不可用。 UpdatePanels解決了這個問題,因爲他們尊重頁面生命週期。您可以像處理普通回發一樣處理事件,但updatepanel使用ajax。 – nmat 2013-05-15 00:24:57