-5

我创建了一个 ASP.NET AJAX 控件,该控件根据将客户端功能添加到 Web 服务器控件来实现IScriptControl。此控件按预期工作 -加载脚本资源时;然而,有问题的问题是脚本资源并不总是被加载。

当从 Full PostBack 加载时,该控件会加载所有适当的引用资源。这并不奇怪。控制工作。它遵循适当的IScriptControl规则,注册脚本控件并呈现适当的脚本描述符。两者GetScriptReferencesGetScriptDescriptions实现了。

现在,当 GetScriptReferences 写成 ..

public IEnumerable<ScriptReference> GetScriptReferences()
{
  return new List<ScriptReference> {
    new ScriptReference("Resource.js", GetType().Assembly.FullName)
  }
}

..那么在部分回发更新中,ScriptManager不会加载资源!

因此,如果控件只能在第一次加载到 Full PostBack 时使用,那么相应的脚本引用已经加载。在它工作的情况下(例如在完整的 PostBack 中),资源获取可以被视为http://dev/ScriptResource.axd?d=...

但是,当通过 .. 加载资源时

public IEnumerable<ScriptReference> GetScriptReferences()
{
  return new List<ScriptReference> {
    new ScriptReference(Page.ClientScript.GetWebResourceUrl(GetType(), "Resource.js"))
  };
}

..然后加载资源,即使在部分回发中也是如此该请求可以在浏览器网络日志中看到为http://dev/WebResource.axd?d=... 我想避免第二种形式,因为我必须手动手动添加Sys.Application.notifyScriptLoaded代码。

正在使用以下配置在自定义 SharePoint 2010 母版页中创建 ASP.NET 3.5 ScriptManager(以便它替换默认的 ScriptManager 控件):

<aspExt:ScriptManager runat="server" ID="MyScriptManager"
    EnablePartialRendering="True" EnablePageMethods="True" EnableViewState="True"
    EnableHistory="True" EnableSecureHistoryState="False"
    EnableScriptLocalization="False" EnableScriptGlobalization="False"
    LoadScriptsBeforeUI="True">
</aspExt:ScriptManager>

ScriptManager.RegisterClientScriptResource通过(从中加载)“工作”手动强制加载脚本,http://dev/ScriptResource.axd?d=..但在这样做时,控件需要破坏IScriptControl 模型并且从 GetScriptReferences 返回任何引用,以便在完全和部分回发情况下确保一致的行为。否则,在 Full PostBack 情况下,当脚本资源实际正确加载时,同一资源将被多次加载。

4

1 回答 1

-1

这似乎是 SharePoint 2010 的一个问题,我终于能够在这篇文章中挖掘出一些信息。

这是 Sharepoint 2010 中的一个已知问题。如果控件最初不可见,则不会加载脚本资源。

.. 如果在部分回发期间添加控件(或使其可见),则会出现“Sharepoint 2010 未在部分回发时发出 javascript 链接”问题。

谢天谢地,

Microsoft 终于在 2011 年 10 月的 Sharepoint 2010 累积更新之一中解决了此问题。安装此更新通常可以解决隐藏 ajax 控件注册其脚本的问题。

看来SharePoint Server 2010 累积更新包(SharePoint server-package):2011 年 10 月 25 日是第一个有此修复的 CU - 虽然我还没有验证这一点。


对于历史参考 - 或者对于像我这样无法确保应用 CU/SP 的穷人 - “工作”是手动注册资源。(这也可以在链接的帖子中找到。)

public class MyComboBox : RadComboBox
{
    protected override System.Collections.Generic.IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
    {
#if MANUAL_SCRIPT_POSTBACK_FIX
        HashSet<string> registeredNames = new HashSet<string>();
        ReadOnlyCollection<RegisteredScript> registeredScripts = ScriptManager.GetCurrent(Page).GetRegisteredClientScriptBlocks();           
        foreach (RegisteredScript registeredScript in registeredScripts)
        {
            registeredNames.Add(registeredScript.Key);
        }
         
        foreach (ScriptReference reference in base.GetScriptReferences())
        {
            if (!registeredNames.Contains(reference.Name))
            {
                ScriptManager.RegisterClientScriptResource(this, typeof(MyComboBox).BaseType, reference.Name);
            }
        }
        return new List<ScriptReference>();
#else
        return base.GetScriptReferences();
#endif     
    }
}
于 2013-12-02T09:19:08.640 回答