使用ScriptManager / ToolkitManager从Microsoft的CDN加载AjaxControlToolkit脚本

时间:2011-02-17 22:35:53

标签: asp.net ajax .net-4.0 ajaxcontroltoolkit cdn

我知道还有另外一个问题要问同样的事情,但现在几个月都没有得到任何关注:https://stackoverflow.com/questions/3786088/how-to-force-ajax-control-toolkit-scripts-loading-from-cdn

我已将网站升级到.NET4,现在我正在使用scriptManager的EnableCDN =“true”标记。我的Ajax脚本正在从Microsoft CDN中引用我的预期,但我似乎无法从CDN加载我的AjaxControlToolkit脚本。相反,它们都通过ScriptResource.axd在本地加载。

我知道CDN文件的位置,我知道每次使用控件时我都可以引用这些文件,但是我有很多遗留代码可以从scriptmanager中自行加载,只需要拉动ScriptResource .axd文件。

有关如何从CDN加载控件工具包脚本的任何建议吗?我已经有了标准的WebForms.js等。

让我知道是否有任何我可以清理的内容,这是我正在使用的脚本管理器:(我已经尝试过toolkitscriptmanager)

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" 
EnableCdn="true" EnableScriptLocalization="false" 
LoadScriptsBeforeUI="false" EnableViewState="false" />

4 个答案:

答案 0 :(得分:11)

如果程序集未在其WebResourceAttributes中定义CDN路径,则EnableCDN将不知道去哪里。就是这样。

但是,如果您知道具有CDN路径的CDN,则可以定义自己的CDN路径。老实说,我不知道最新的ACT是否在CDN上。如果您使用的版本是40412,那么是,它是: http://www.asp.net/ajaxlibrary/CDNACT40412.ashx

您定义自己路径的方式在我的博客条目中有所描述(在另一个答案中也有提及):
http://weblogs.asp.net/infinitiesloop/archive/2009/11/23/asp-net-4-0-scriptmanager-improvements.aspx

以下是一个例子,如下所述:

void Application_Start(object sender, EventArgs e) {
    ScriptManager.ScriptResourceMapping.AddDefinition("Foo.js", typeof(FooControl).Assembly, new ScriptResourceDefinition {
        ResourceName = "Foo.js",
        ResourceAssembly = typeof(FooControl).Assembly,
        CdnPath = "http://yadda-yadda/foo.js",
        CdnDebugPath = "http://yadda-yadda/foo.debug.js",
    });
}

以下是发生的事情。首先,存在一个程序集,我们称之为Foo.dll。它包含一个脚本作为名为“Foo.js”的嵌入式资源(.js扩展名是可选的)。因此,asp:ScriptReferences(在页面上或来自服务器控件)到该资源将转到ScriptResource.axd。程序集的WebResourceAttribute脚本没有定义CDN路径,所以如果你打开CdnMode它仍然会去那里。

你想解决这个问题,所以你所做的就是定位那个脚本。为此,您必须参考其程序集和名称。他们一起识别脚本(如果你愿意的话,它是“主键”)。 AddDefinition的前两个参数实现了这一点。

现在您已经定位它,您可以完全重新定义该脚本的含义。你把它放在另一个程序集,另一个路径,定义cdn路径..任何东西。

定义的ResourceName和ResourceAssembly属性确定脚本确实仍属于它来自的同一程序集。如果你打算从CDN加载,这似乎是不必要的。但它做了两件事:(1)如果关闭CDN它仍然有效,(2)它仍然能够确定资源的调试版本(foo.debug.js)或任何LOCALIZED版本(例如foo.fr-FR.js)存在于程序集中,从而知道CDN是否包含该版本(因为它不能很好地从服务器检查)。因此,最好将定义赋予所有者(请注意,如果您未指定它们,则不会默认为原始所有者。)

CdnPath和CdnDebugPath属性是显而易见的,这是您的最终目标。 EnableCdn现在应该可以工作了!

我建议您尽可能使用ScriptMapping来定义脚本的详细信息,然后按名称而不是路径引用它们。保持标记简单,因为你可以在一个地方定义脚本的所有细节,所以它更加干燥。

现在......你如何使用AjaxControlToolkit做到这一点?

您将不得不为工具包中的每个脚本编写其中一个映射。这不会很有趣,有几十个和几十个。不要为每个发行版和调试脚本编写单独的错误。这两个是一对,并用1映射定义。还有其中一些的本地化版本,但我不打扰它 - 消息是针对开发人员的错误消息,无论如何真的不需要本地化,因为该功能旨在本地化内容以便结束用户。

一件事 - 在1或2个ACT脚本上试一试,以确保你做对了。此外,我还没有提到另外一个复杂性。

还记得当我说名称和大会聚集在一起来识别一个脚本(它的“主键”)吗?这是真的,但是对于来自System.Web.Extensions或所谓的“AjaxFrameworkAssembly”的脚本有一个特殊规则。在这种情况下,指定空程序集或使用完全缺少该参数的重载是等效的。什么是“AjaxFrameworkAssembly”?好吧,System.Web.Extensions包含一个鲜为人知的特性,它允许程序集通过程序集级属性将自身断言为“AjaxFrameworkAssembly”。这样做意味着“我是包含ms ajax脚本的程序集,你应该来找我而不是System.Web.Extensions”。 ACT使用它来“升级”System.Web.Extensions中嵌入的脚本。它有自己的那些具有更高版本号的脚本的副本。所有你需要做的就是引用程序集,并且presto,脚本会自动重定向到来自那里。这里的重点是,您可能无法在所有这些映射中指定程序集。但是,试一试,不要相信我的话。

这是InfinitiesLoop的答案。我现在回到你定期安排的节目:)

答案 1 :(得分:2)

我也很难解决这个问题,并最终发现脚本的ACT版本也放在了CDN上,但没有文档说明它们是。

根路径为:http://ajax.aspnetcdn.com/ajax/act/40412/

例如,MicrosoftAjaxCore.js文件的ACT版本的路径是: http://ajax.aspnetcdn.com/ajax/act/40412/MicrosoftAjaxCore.js

要确保始终使用此路径 - 在应用程序加载时执行一次,然后在使用ToolkitScriptManager的每个页面上使用 - 请在Global.asax中使用以下代码行。请注意,您需要一个代码块/脚本文件。

ScriptManager.ScriptResourceMapping.AddDefinition("MicrosoftAjaxCore.js", new ScriptResourceDefinition
    {
        ResourceName = "MicrosoftAjaxCore.js",
        CdnPath = "http://ajax.aspnetcdn.com/ajax/act/40412/MicrosoftAjaxCore.js",
        CdnDebugPath = "http://ajax.aspnetcdn.com/ajax/act/40412/MicrosoftAjaxCore.debug.js"
    });

我还为ScriptManager配置了属性FrameworkMode="Disabled"和指定的所需文件,将它们链接到ACT版本,否则使用System.Web.Extensions中的版本。确保指出正确版本的ACT。

<asp:ScriptReference Name="MicrosoftAjaxCore.js" Assembly="AjaxControlToolkit, Version=4.1.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e" />
<asp:ScriptReference Name="MicrosoftAjaxComponentModel.js" Assembly="AjaxControlToolkit, Version=4.1.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e"  />
<asp:ScriptReference Name="MicrosoftAjaxSerialization.js" Assembly="AjaxControlToolkit, Version=4.1.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e"  />
<asp:ScriptReference Name="MicrosoftAjaxNetwork.js" Assembly="AjaxControlToolkit, Version=4.1.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e"  />
<asp:ScriptReference Name="MicrosoftAjaxWebServices.js" Assembly="AjaxControlToolkit, Version=4.1.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e"  />
<asp:ScriptReference Name="MicrosoftAjaxWebForms.js" Assembly="AjaxControlToolkit, Version=4.1.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e" />

答案 2 :(得分:1)

我倾向于回答:这是不可能的。我很乐意听到,但我的理解是脚本管理器将始终提取本地ajaxtoolkit文件并将其作为ScriptResource.axd提供。

如问题中所述,我知道您可以包含自己的脚本引用(对于Microsoft CDN中的文件),但是您必须在每个文件请求中指定您想要/需要的文件,而不是让脚本管理器处理文件请求对你而言。

答案 3 :(得分:0)

我还没有尝试过,但在InfinitiesLoop博客上的解释(http://weblogs.asp.net/infinitiesloop/archive/2009/11/23/asp-net-4-0-scriptmanager -improvements.aspx)当然听起来很合理。

现在,WebResourceAttribute上有一个新属性:CdnPath。不要过于关注它是一个硬编码的URL。稍后会详细介绍。

[assembly:WebResource(“Foo.js”,“application / x-javascript”,CdnPath =“http://foo.com/foo/bar/foo.js”)]

当EnableCdn属性设置为true时,ScriptManager会查找此属性,并且只使用该路径而不是程序集资源的ScriptResource.axd路径。很简单。这意味着您也可以为自己的程序集资源脚本提供自己的CDN路径。至于托管脚本的位置,嗯,这取决于你。