1

我有一个在 ASP.Net 下运行的网站。它有许多 ascx 控件,每个控件代表一个不同的页面。母版页将调用LoadControl()ascx,然后将其添加到面板中。然后 ascxPage_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 时调用其保存函数。这是隐藏的代码,它希望保留其视图状态。所以我想我必须有一个回发。我宁愿不必将 C# 保存函数重写为带有传入参数的自己的 ashx 调用;有很多这样的页面,不值得把它们都重写一遍。

我在 DocumentMetadata.ascx 中有以下代码来设置按钮按下来做某事。

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

});

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

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

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

4

2 回答 2

1

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

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

Post-backs 是老派技术,UpdatePanels 只是 ajax 的一个讨厌的实现。花点时间为您的应用程序和您自己做正确的事情,您都会因此而变得更好。

于 2013-05-15T14:29:02.170 回答
0

如果您使用UpdatePanel ,您在此处所做的事情会更容易完成。它通过部分回发在客户端工作,并保留了 ASP 页面生命周期。您可以使用 UpdatePanels 包装您的#property_tab和您#btnSave的并管理回发事件服务器端。

于 2013-05-14T18:38:56.990 回答