在由jQuery动态添加的ASP.Net控件上执行回发

时间:2013-05-14 18:26:53

标签: c# jquery asp.net postback

我有一个在ASP.Net下运行的网站。它有许多ascx控件,每个控件代表一个不同的页面。母版页将在ascx上调用LoadControl(),然后将其添加到面板。然后,ascx Page_Load()将个人保存功能连接到页面上的事件,以便母版页上的“保存”按钮可以做正确的事情。这一切都有效。

我现在正试图变得更有活力并且更多地使用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时调用其save函数。这是代码背后,它希望保留其viewstate。所以我假设我必须有一个回发。我宁愿不要用传入的参数重写C#save函数作为自己的ashx调用;有很多像这样的页面,重写它们都不值得。

我在DocumentMetadata.ascx中有以下代码来设置按钮按下以执行某些操作。

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

});

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

我通过在Javascript中调用__doPostBack()进行了实验,但后来我得到错误:“viewstate MAC验证失败。如果此应用程序由Web场或群集托管,请确保配置指定相同的validationKey和验证算法.AutoGenerate不能在集群中使用。“作为一个实验,我试图从我的web.config中删除我的机器密钥配置,但这似乎没有帮助。

有没有办法使用JavaScript来调用加载了jQuery的ascx控件后面的代码?

2 个答案:

答案 0 :(得分:1)

通过ajax加载.ascx控件与加载字符串相同。它是单向管道,并且该控件没有可用的回发通信。 UpdatePanel解决方案也不起作用(并且它们很糟糕)。

我的建议是创建客户端模板,使用类似Mustache.js的东西,然后通过ajax加载JSON数据来填充这些模板,使用web服务加载ajax以与服务器/数据库通信。通过分离代码,它将更容易维护,您将能够重用更多代码,提高效率等。

Post-backs是旧学校技术,而UpdatePanels只是一个令人讨厌的ajax实现。花一些时间做正确的事,无论是你的应用还是你自己,你都会因此而变得更好。

答案 1 :(得分:0)

如果您使用UpdatePanel,可以更轻松地完成此处的操作。它在客户端使用部分回发,并保留ASP页面生命周期。 您可以使用UpdatePanel包装#property_tab#btnSave并管理回发事件服务器端。