2013-05-14 80 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