本文中的信息都是收集來的,來源很多,無法一一列出,望見諒。內容僅作為個人的知識管理。
Windows SharePoint Services v3 基於ASP.NET 2.0構建。Microsoft ASP.NET AJAX 1.0在MOSS之後推出,因此在某些情況下,ASP.NET AJax 和 SharePoint之間存在一些兼容性問題,這些問題將會在Windows SharePoint Services SP1中解決。在此之前要在SharePoint中使用ASP.Net AJax技術,需要進行一些特殊的部署步驟。
注意:
UpdatePanel在 webpart中使用會有所限制。詳細情況請查考ASP.Net AJax的文檔。並不是所有的控件都可以在UpdatePanel中使用。
如果啟用了輸出緩存,就不能使用ASP.Net AJax,否則會出現錯誤。經典的性能與時效的矛盾。
在SharePoint中使用Microsoft ASP.Net AJax 1.0技術帶來的好處:
可以形成一套完整的客戶端腳本資源庫,並積累一些可重用的部件。
可以使用 JSON展示我們的Web服務數據, 結果可以很容易的在JavaScript/AJax應用程序中使用。
利用擴展中的技術構建WebPart可以提供高交互性的樣式,比如一個具備自動完成功能的 textbox.
在WebPart中利用 UpdatePanel,實現無回調的交互,減少刷新頁面的次數。
下面是部署使用了Microsoft ASP.Net AJax 1.0技術的組件前的環境准備步驟。(只需在新安裝的環境中部署一次,以後添加Webpart就不用了)
下載並在Web服務器場上安裝ASP.Net AJax
首先,必須安裝 "ASP.NET 2.0 AJAX Extensions 1.0" ,可以從AJax.ASP.Net下載。
為Microsoft ASP.Net AJax 1.0擴展 SharePoint web.config
我們需要為AJax注冊一些特定的條目。 編輯SharePoint的 web.config文件,該文件通常位於如下目錄:
c:\inetpub\wwwroot\wss\virtualdirectorIEs\80
添加 <sectionGroup>元素到 <configSections>標記: <configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJSonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
添加 <controls> 節的內容,放在 <system.web>/<pages> 標記中。 <pages>
<controls>
<add tagPrefix="ASP" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</controls>
</pages>
在<compilation>標記內的<assemblies> 標記中添加下面的內容: <assemblIEs>
<add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</assemblIEs>
在 <httpHandlers> 節中添加下面的內容: <httpHandlers>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<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"/>
<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"/>
</httpHandlers>
在 HttpModules 節中添加下面的注冊內容,放在所有已有的注冊內容下面 <httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpModules>
在<SharePoint>/<SafeControls>節中,添加一條 SafeControl ,用於 Microsoft AJax Extensions的System.Web.UI命名空間。 <SafeControls>
<SafeControl Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TypeName="*" Safe="True" />
</SafeControls>
最後,添加下面的 configuration標記到 web.config文件末尾, 在結束標記<configuration>前面。
<system.web.extensions>
<scripting>
<webServices>
<!-- Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate. -->
<!--
<authenticationService enabled="true" requireSSL = "true|false"/>
-->
<!-- 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. -->
<!--
<profileService enabled="true"
readAccessPropertIEs="propertyname1,propertyname2"
writeAccessPropertIEs="propertyname1,propertyname2" />
-->
</webServices>
<!--
<scriptResourceHandler enableCompression="true" enableCaching="true" />
-->
</scripting>
</system.web.extensions>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<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"/>
<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" />
</handlers>
</system.webServer>
利用AJaxBaseWebPart進行開發
編寫使用該擴展的WebPart最簡單的辦法就是直接繼承別人寫好的AJaxBaseWebPart。下面是我用的一個。您也可以用其他的,或自己寫一個。
下面是命名空間引用部分:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI.WebControls.WebParts;
using System.XML.Serialization;
using System.Web.UI;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.UtilitIEs;
using System.Web.UI.WebControls;
using System.Drawing;
下面是AJaxBaseWebPart類的實現部分:
/// <summary>
/// A base class that implements all the functionality required to use ASP.Net AJax extensions inside WSS
/// </summary>
[XMLRoot(Namespace = "Deps.AJaxBaseWebpart")]
public abstract class AJaxBaseWebpart : Microsoft.SharePoint.WebPartPages.WebPart
{
/*
* The idea and the code behind this base web part was taken from Erics blog post at:
* http://www.capdes.com/2007/02/AJaxbasepart_easy_ASPnet_20_aj.Html
* This basically manages the presence and configuration of the ScriptManager
* which is required by ASP.Net AJax extensions to handle postbacks, ect. This web part also includes
* a common method for handling errors.
*/
#region Declarations
private string _ValidationGroupId;
private ValidationSummary _ErrorContainer;
private ScriptManager _AJaxManager;
#endregion
#region Constructor
public AJaxBaseWebpart()
{
}
#endregion
#region Methods
/// <summary>
/// Used to provide a common way to display errors to the user of the current web part.
/// </summary>
/// <param name="message">Description of the error that occured.</param>
public void RegisterError(string message)
{
if (this.Controls.Contains(_ErrorContainer))
{
//this way of generating a unique control id is used in some of the OOB web parts
int uniqueCounter;
if (HttpContext.Current.Items["GetUniqueControlId"] != null)
{
uniqueCounter = (int)HttpContext.Current.Items["GetUniqueControlId"];
}
else
{
uniqueCounter = 0;
}
uniqueCounter++;
HttpContext.Current.Items["GetUniqueControlId"] = uniqueCounter;
//create a custom validator to register the current error message with the ValidationSummary control
CustomValidator cv = new CustomValidator();
cv.ID = string.Concat("_Error_", uniqueCounter);
cv.ValidationGroup = _ValidationGroupId;
cv.Display = ValidatorDisplay.None;
cv.IsValid = false;
cv.ErrorMessage = message;
this.Controls.Add(cv);
}
else
{
//if RegisterError is called before the CreateChildControls override in AJaxBasePart then transfer the user to an error page using the SPUtility
SPUtility.TransferToErrorPage("The CreateChildControls function of the AJaxBasePart has not been called. You probably need to add \"base.CreateChildControls()\" to the top of your CreateChildControls override.");
}
}
/// <summary>
/// Needs to be called to ensure that the ValidationSummary control is registered on the page. Any child web parts will need to have base.CreateChildControls() at the top of their own CreateChildControls override.
/// </summary>
protected override void CreateChildControls()
{
base.CreateChildControls();
if (!this.Controls.Contains(_ErrorContainer))
{
_ValidationGroupId = Guid.NewGuid().ToString();
_ErrorContainer = new ValidationSummary();
_ErrorContainer.ID = "_ErrorContainer";
_ErrorContainer.ValidationGroup = _ValidationGroupId;
_ErrorContainer.BorderStyle = BorderStyle.Solid;
_ErrorContainer.BorderWidth = Unit.Pixel(3);
_ErrorContainer.BorderColor = Color.Red;
this.Controls.Add(_ErrorContainer);
}
}
#endregion
#region Events
/// <summary>
/// Oninit fires before page load. Modifications to the page that are necessary to support AJax are done here.
/// </summary>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//get the existing ScriptManager if it exists on the page
_AJaxManager = ScriptManager.GetCurrent(this.Page);
if (_AJaxManager == null)
{
//create new ScriptManager and EnablePartialRendering
_AJaxManager = new ScriptManager();
_AJaxManager.EnablePartialRendering = true;
// Fix problem with postbacks and form actions (DevDiv 55525)
Page.ClIEntScript.RegisterStartupScript(typeof(AJaxBaseWebpart), this.ID, "_spOriginalForMaction = document.forms[0].action;", true);
//tag:"form" att:"onsubmit" val:"return _spFormOnSubmitWrapper()" blocks async postbacks after the first one
//not calling "_spFormOnSubmitWrapper()" breaks all postbacks
//returning true all the time, somewhat defeats the purpose of the _spFormOnSubmitWrapper() which is to block repetitive postbacks, but it allows MS AJax Extensions to work properly
//its a hack that hopefully has minimal effect
if (this.Page.Form != null)
{
string formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
if (!string.IsNullOrEmpty(formOnSubmitAtt) && formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
//add the ScriptManager as the first control in the Page.Form
//I don't think this actually matters, but I did it to be consistent with how you are supposed to place the ScriptManager when used declaritevly
this.Page.Form.Controls.AddAt(0, _AJaxManager);
}
}
}
#endregion
#region PropertIEs
/// <summary>
/// Exposes the Page's script manager. The value is not set until after OnInit
/// </summary>
[WebPartStorage(Storage.None)]
public ScriptManager AJaxManager
{
get { return _AJaxManager; }
set { _AJaxManager = value; }
}
#endregion
}
開發時只要繼承這個WebPart就可以添加UpdatePanel,並在裡面添加其他控件了。