[翻译]ASP.NET AJAX与SharePoint的集成

原文: Integrating ASP.NET AJAX with SharePoint 来自微软SharePoint Team Blog

Microsoft ASP.NET AJAX 1.0: 一点背景

================================

Microsoft ASP. NET AJAX 1.0 允许开发人员使用最新的Ajax技术建立Web2.0站点. 

ASP.NET AJAX 扩展了 ASP.NET 2.0 并且使得许多新工具和技术都变的可用了, 他们可以帮助你你更快的建立应用程序:

  • JavaScript的扩展.  ASP.NET AJAX 扩展了JavaScript 库, 从而为JavaScript带来了标准的面向对象概念. 它带来了一个正式的类型声明系统, 还支持集成. 它还提供了很多开箱即用(out of the box)的类型, 包括诸如方便你在web services上进行工作的Sys.Net.WebRequest 类型. 最后, 它帮助我们抽象一些跨浏览器的问题, 比如说XML元素遍历. 这使得创建那些被应用在丰富的因特网应用程序中的健壮的JavaScript库和框架更加容易了.  
  • ASP.NET 控件扩展器.  扩展器(Extenders)是额外的ASP.NET控件, 这些控件能够扩展已经存在的控件, 提供给他们额外的Ajax能力. 一个普通的例子是一个extender允许已经存在的textbox控件拥有自动补全功能, 而不需要对于被扩展的控件做任何修改(自动填充扩展器autocomplete extender包含在ASP.NET AJAX Control Toolkit中.)
  • UpdatePanels.  UpdatePanels允许你的已经存在的ASP.NET控件和web part能够达到流畅的, 无回发(no-postback)的更新基于Ajax的应用程序, 而更新对于你的控件或者web part的代码的重写量是最低限度的. 很简单地, UpdatePanel内的控件原来需要post back来更新它们的数据, 而现在他们会被通过Ajax风格的回调来路由, 从而引导了一个静默地回服务器的更新. 这使得你的应用程序"postback"更少, 使得与你的控件的互动更加的无缝化.

有了Microsoft ASP.NET AJAX 1.0, 你可以建造更动态的应用程序, 这样的应用程序拥有更接近与那些你可能在标准客户端应用程序中看到的, 丰富的无中断风格的互动.

Microsoft ASP.NET AJAX 1.0和SharePoint

================================

Windows SharePoint Services的第三个版本直接建立在ASP.NET 2.0之上; 所以, ASP.NET AJAX的许多能力可以在SharePoint上直接地工作.

然而, 有些情况下, 有那么几个在可能在第一个Windows SharePoint Services中解决掉的ASP.NET AJAX与SharePoint之间集成的问题. 由于这个原因, 直到WSS SP1发布, 我们还不能正式地为在一个SharePoint站点上的ASP.NET AJAX的使用提供微软产品支持服务(Microsoft Product Support Services), 这篇文档的目的是给开发人员在评估ASP.NET AJAX和WSS3.0上提供一些指导方针.

具体来说, 在你的web parts和控件中使用UpdatePanel中, 有一些限制. 下面描述的一些方式方法可以用来解决这些限制, 但是这些只是变通方案(workarounds), 而且有可能在你的应用程序中引发一些问题.
下面是一些SharePoint中的通常的场景, 在这些场景下, 你应该可以通过Microsoft ASP.NET AJAX 1.0达到你的目的:

  1. 建立一个更强大的, 可以复用的JavaScript库, 你可以在你的web控件中和web part中使用它们.
  2. 允许你的Web Services通过JSON来渲染, 导致JavaScript或Ajax应用程序可以更容易地使用这些Web Services.
  3. 建立一个可以使用Extender的优势的web part, 从而为用户提供更丰富的互动风格, 比如说在textbox中的自动填充.
  4. 为了获得更流畅的 无回发的交互, 而在你的web part中使用一个UpdatePanel. (这还需要一点权变方案.)

为SharePoint页面添加Microsoft ASP.NET AJAX技术

=================
为了使用Microsoft ASP.NET AJAX 1.0来扩展你的SharePoint站点, 你需要执行下列的几个步骤.

  • 首先, 你需要在你的场中的服务商下载并安装ASP.NET AJAX.
  • 第二, 你需要扩展你的web.config文件, 添加一些设置来启动ASP.NET AJAX 技术. 
  • 第三, 你需要添加ASP.NET AJAX Script Manager到你的母版页中, 来启动一些Extenders或者是UpdatePanels的场景.

在你的场中的服务器上安装ASP.NET AJAX

=================

你需要从ajax.asp.net安装完整的"ASP.NET 2.0 AJAX Extensions 1.0"

使用Microsoft ASP. NET AJAX 1.0 扩展你的web.config

=================

使用ASP.NET AJAX扩展SharePoint的web.config文件需要交错一些Ajax的注册条目, 内嵌在WSS的注册条目内. 要这样做, 你需要编辑你的SharePoing web.config文件, 其典型地存在于类似c:\inetpub\wwwroot\wss\virtualdirectories\80的目录中.

1. 在<configSections>标签中添加一个<sectionGroup>元素

Code Snippet
  1. <configSections>
  2.   <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
  3.     <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
  4.       <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
  5.       <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
  6.         <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" />
  7.         <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
  8.         <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
  9.       </sectionGroup>
  10.     </sectionGroup>
  11.   </sectionGroup>
  12. </configSections>

2. 添加一个<controls>部分, 作为<system.web>/<pages>标签的孩子

Code Snippet
  1. <pages>
  2.   <controls>
  3.     <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  4.   </controls>
  5. </pages>

3. 添加下面的标签到<assemblies>标签, 在<compliation>标签中

Code Snippet
  1. <assemblies>
  2.   <add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  3. </assemblies>

4. 添加一些新的注册信息到<httpHandlers>部分的结尾

Code Snippet
  1. <httpHandlers>
  2.   <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  3.   <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  4.   <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
  5. </httpHandlers>

5. 添加一些新的注册信息到HttpModules部分, 在任何已经存在的注册信息之下:

Code Snippet
  1. <httpModules>
  2.   <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  3. </httpModules>

6. 在<SharePoint>/<SafeControls>部分里, 为Microsoft Ajax Extensions中的System.Web.UI命名空间添加一个SafeControl条目.

Code Snippet
  1. <SafeControls>
  2.   <SafeControl Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TypeName="*" Safe="True" />
  3. </SafeControls>

7. 最后, 添加如下的配置标签, 在web.config文件, 在靠近底部, 在最后的<configuration>标签之前:

Code Snippet
  1. <system.web.extensions>
  2.   <scripting>
  3.     <webServices>
  4.       <!-- Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate. -->
  5.       <!--
  6.         <authenticationService enabled="true" requireSSL = "true|false"/>
  7.       -->
  8.       <!-- Uncomment these lines to enable the profile service. To allow profile properties to be retrieved and modified in ASP.NET AJAX applications, you need to add each property name to the readAccessProperties and writeAccessProperties attributes. -->
  9.       <!--
  10.       <profileService enabled="true"
  11.                       readAccessProperties="propertyname1,propertyname2"
  12.                       writeAccessProperties="propertyname1,propertyname2" />
  13.       -->
  14.     </webServices>
  15.     <!--
  16.       <scriptResourceHandler enableCompression="true" enableCaching="true" />
  17.       -->
  18.   </scripting>
  19. </system.web.extensions>
  20. <system.webServer>
  21.   <validation validateIntegratedModeConfiguration="false"/>
  22.   <modules>
  23.     <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  24.   </modules>
  25.   <handlers>
  26.     <remove name="WebServiceHandlerFactory-Integrated" />
  27.     <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
  28.          type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  29.     <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  30.     <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  31.   </handlers>
  32. </system.webServer>

添加一个ScriptManager到一个SharePoint母版页中

=================

许多ASP.NET AJAX技术需要页面中包括一个.NET ScriptManager控件.

尽管可能在某些情况下, 在一个控件中动态地添加一个script manager是有可能的, 很多情况下, 控件并不能在页面生命周期的尽早的时候添加script manager, 这取决于控件的是如何被使用的, 所以在控件中添加script manager有点麻烦. 还有, 控件实现者会需要保证他们控件的多个实例并不会导致页面中对于script manager的多次添加. 基于这些原因, 并不推荐动态地从另一个控件中插入ScriptManager控件.

为了静态地在页面中嵌入一个Script Manager, 推荐在站点的母版页中添加ScriptManager.

为了做到这一点, 打开站点的母版页. 典型地, 这个的位置在<site url>/_catalogs/masterpage. 你可以在比方说Microsoft SharePoint Designer这样的编辑器中编辑这个文件, 或者直接通过DAV用Notepad来打开你的母版页库(典型的位置在\_catalogs\masterpage">\\server\<pathtosite>\_catalogs\masterpage)

添加下面的代码到你页面的markup中. 一个推荐的位置是刚刚好在WebPartManager注册之处的下面(搜索<WebPartPages:SPWebPartManager id="m" runat="Server" />):

  1. <asp:ScriptManager runat="server" ID="ScriptManager1"></asp:ScriptManager>

在SharePoint中使用UpdatePanels

=================

UpdatePanels是ASP.NET AJAX的一项非常有价值的附加物, 并且代表了转换现有的标准的ASP.NET控件和部件, 使它们具备Ajax技术优势的最简单的方式. 然而在Windows SharePoint Services中, 有一些更改可能会挡住到我们添加ASP.NET AJAX技术的路.

Windows SharePoint Services JavaScript有一个“form onSubmit wrapper”, 它被用来覆盖默认的表单动作. 这个东西的实现保证了有些类型的URL, 比如说带有双字节字符的URL,在完整回发和异步回调的场景下也可以正常工作. 然而, 如果你的场景不涉及到双字节宽字符的URL, 你可以成功地禁用这个权宜之计, 同样可以获得使用ASP.NET AJAX UpdatePanels的能力.

为了做到这一点, 你需要注册一个客户端启动脚本, 它会禁用这个workaround, 还会重设默认的表单动作:

  1. <script type='text/javascript'>_spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;</script>

这段脚本可以直接地嵌入页面中, 或者通过使用UpdatePanel的控件注射进入页面中. 一下是一个非常简单的ASP.NET Web Part的例子, 它使用了UpdatePanel能力:

Code Snippet
  1. using System;
  2. using System.Collections;
  3. using System.Text;
  4. using System.Web.UI.WebControls;
  5. using System.Web.UI.WebControls.WebParts;
  6. using System.Web.UI;
  7.  
  8. namespace MS.Samples
  9. {
  10.     public class AjaxUpdatePanelPart : WebPart
  11.     {
  12.         private Label label;
  13.         private TextBox textBox;
  14.  
  15.         protected override void CreateChildControls()
  16.         {
  17.             base.CreateChildControls();
  18.  
  19.             this.EnsureUpdatePanelFixups();
  20.  
  21.             UpdatePanel up = new UpdatePanel();
  22.  
  23.             up.ID = "UpdatePanel1";
  24.             up.ChildrenAsTriggers = true;
  25.             up.UpdateMode = UpdatePanelUpdateMode.Conditional;
  26.  
  27.             this.Controls.Add(up);
  28.  
  29.             this.textBox = new TextBox();
  30.             this.textBox.ID = "TextBox";
  31.             up.ContentTemplateContainer.Controls.Add(this.textBox);
  32.  
  33.             this.label = new Label();
  34.             this.label.Text = "Enter your name.";
  35.             up.ContentTemplateContainer.Controls.Add(this.label);
  36.  
  37.             Button button = new Button();
  38.             button.Text = "Say Hello";
  39.             button.Click += new EventHandler(HandleButtonClick);
  40.             up.ContentTemplateContainer.Controls.Add(button);
  41.         }
  42.  
  43.         private void HandleButtonClick(object sender, EventArgs eventArgs)
  44.         {
  45.             this.label.Text = "Hello " + this.textBox.Text;
  46.         }
  47.  
  48.         private void EnsureUpdatePanelFixups()
  49.         {
  50.             if (this.Page.Form != null)
  51.             {
  52.                 string formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
  53.                 if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
  54.                 {
  55.                     this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
  56.                 }
  57.             }
  58.  
  59.             ScriptManager.RegisterStartupScript(this, typeof(AjaxUpdatePanelPart), "UpdatePanelFixup", "_spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;", true);
  60.         }
  61.     }
  62. }

输出缓存与ASP.NET AJAX

==================

ASP.NET AJAX基础架构并没有与输出缓存特性进行兼容. 这个输出缓存基础架构是managed content pages的一个特征组件, 就像那些在Microsoft Office SharePoint Server中被web content management特性支持的managed content pages一样. 基于这个原因, 许多涉及到输出缓存特性的场景下, 就不能利用类似UpdatePanel组件的优势了. 然而, 你可以成功地使用其他的ASP.NET AJAX特性, 比如说跟你的输出缓存了的页面结合的JavaScript库

支持输出缓存是下一个版本ASP.NET AJAX基础架构的目标.

结论

=============================

Microsoft ASP.NET AJAX 1.0为建立丰富的开启Ajax的应用程序提供了优秀的创建工具. 与SharePoint 平台的威力结合在一起, 你可以创建强大的使用上这些优秀技术的Web2.0应用程序, 尽管集成上面还有一点点限制.

原文作者: Mike Ammerlaan, Program Manager

原文地址:https://www.cnblogs.com/awpatp/p/1612447.html