La información de este artículo se recopila de muchas fuentes, por lo que no puedo enumerarlas todas. Pido disculpas por ello. El contenido es únicamente para la gestión del conocimiento personal.
Windows SharePoint Services v3 se basa en ASP.NET 2.0. Microsoft ASP.NET AJAX 1.0 se lanzó después de MOSS, por lo que, en algunos casos, existen algunos problemas de compatibilidad entre ASP.NET AJAX y SharePoint, que se resolverán en Windows SharePoint Services SP1. Antes de esto, el uso de la tecnología ASP.NET AJAX en SharePoint requería algunos pasos de implementación especiales.
Nota:
Existen restricciones sobre el uso de UpdatePanel en el elemento web. Consulte la documentación de ASP.NET AJAX para obtener más detalles. No todos los controles se pueden utilizar en UpdatePanel.
Si el almacenamiento en caché de resultados está habilitado, no podrá utilizar ASP.NET AJAX o se producirá un error. La clásica contradicción entre desempeño y puntualidad.
Beneficios de utilizar la tecnología Microsoft ASP.NET AJAX 1.0 en SharePoint:
Se puede formar una biblioteca completa de recursos de scripts de cliente y se pueden acumular algunos componentes reutilizables.
Los datos de nuestro servicio web se pueden mostrar usando JSON y los resultados se pueden usar fácilmente en aplicaciones JavaScript/Ajax.
La creación de WebParts utilizando la tecnología de las extensiones puede proporcionar estilos altamente interactivos, como un cuadro de texto con funcionalidad de autocompletar.
Utilice UpdatePanel en WebPart para lograr una interacción sin devolución de llamadas y reducir la cantidad de actualizaciones de página.
Los siguientes son los pasos de preparación del entorno antes de implementar componentes que utilizan la tecnología Microsoft ASP.NET AJAX 1.0. (Solo necesita implementarlo una vez en el entorno recién instalado y no necesitará agregar Webpart más adelante).
Descargue e instale ASP.NET AJAX en la granja de servidores web.
Primero, debe instalar "ASP.NET 2.0 AJAX Extensions 1.0". ", que se puede descargar desde ajax.asp .net download.
Ampliación de SharePoint web.config para Microsoft ASP.NET AJAX 1.0
Necesitamos registrar algunas entradas específicas para Ajax. Edite el archivo web.config de SharePoint, que normalmente se encuentra en el siguiente directorio:
c:inetpubwwwrootwssvirtualdirectories80
Agregue el elemento <sectionGroup> a la etiqueta <configSections>: <configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Versión=1.0.61025.0, Cultura=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" enableDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Versión=1.0.61025.0, Cultura=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" enableDefinition="Everywhere" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" enableDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Versión=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" enableDefinition="MachineToApplication" />
</secciónGrupo>
</secciónGrupo>
</secciónGrupo>
</configSections>
Agregue el contenido de la sección <controls> dentro de las etiquetas <system.web>/<pages>. <páginas>
<controles>
<add tagPrefix="asp" namespace="System.Web.UI" ensamblaje="System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35"/>
</controles>
</páginas>
Agregue el siguiente contenido dentro de la etiqueta <assemblies> dentro de la etiqueta <compilation>: <assemblies>
<agregar ensamblaje="System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35"/>
</conjuntos>
Agregue el siguiente contenido en la sección <httpHandlers>: <httpHandlers>
<add verb="*" path="*.asmx" validar="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken= 31bf3856ad364e35"/>
<add verb="*" path="*_AppService.axd" validar="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken =31bf3856ad364e35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35" validar=" falso"/>
</httpHandlers>
Agregue el siguiente contenido de registro en la sección HttpModules, debajo de todo el contenido de registro existente <httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpModules>
En la sección <SharePoint>/<SafeControls>, agregue un SafeControl para el espacio de nombres System.Web.UI de Microsoft Ajax Extensions. <Controles seguros>
<SafeControl Assembly="System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TypeName="*" Safe="True" />
</SafeControls>
Finalmente, agregue la siguiente etiqueta de configuración al final del archivo web.config, justo antes de la etiqueta <configuration> de cierre.
<extensiones.web.sistema>
<scripting>
<servicios web>
<!-- Descomente esta línea para habilitar el servicio de autenticación. Incluya requireSSL="true" si corresponde.
<!--
<authenticationService habilitado="true" requireSSL = "true|false"/>
-->
<!-- Descomente estas líneas para habilitar el servicio de perfil. Para permitir que las propiedades del perfil se recuperen y modifiquen en aplicaciones ASP.NET AJAX, debe agregar cada nombre de propiedad a los atributos readAccessProperties y writeAccessProperties -->.
<!--
<profileService habilitado="verdadero"
readAccessProperties="nombre de propiedad1, nombre de propiedad2"
writeAccessProperties="nombre de propiedad1, nombre de propiedad2" />
-->
</serviciosweb>
<!--
<scriptResourceHandler enableCompression="true" enableCaching="true" />
-->
</scripting>
</sistema.web.extensiones>
<sistema.servidorweb>
<validación validarIntegratedModeConfiguration="false"/>
<módulos>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35"/>
</módulos>
<manipuladores>
<eliminar nombre="WebServiceHandlerFactory-Integrated" />
<añadir nombre="ScriptHandlerFactory" verb="*" ruta="*.asmx" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Versión=1.0.61025.0, Cultura=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Versión=1.0.61025.0, Cultura =neutral, PublicKeyToken=31bf3856ad364e35" />
</manipuladores>
</sistema.servidorweb>
Desarrolle usando AjaxBaseWebPart
La forma más fácil de escribir un WebPart que use esta extensión es heredar directamente el AjaxBaseWebPart escrito por otros. A continuación se muestra el que yo uso. También puedes utilizar otro o escribir uno tú mismo.
Aquí está la parte de referencia del espacio de nombres:
usando Sistema;
usando System.Collections.Generic;
usando System.Text;
usando System.Web;
usando System.Web.UI.WebControls.WebParts;
usando System.Xml.Serialization;
utilizando System.Web.UI;
utilizando Microsoft.SharePoint.WebPartPages;
utilizando Microsoft.SharePoint.Utilities;
usando System.Web.UI.WebControls;
usando System.Drawing;
La siguiente es la parte de implementación de la clase AjaxBaseWebPart:
/// <resumen>
/// Una clase base que implementa toda la funcionalidad necesaria para usar extensiones ASP.net Ajax dentro de WSS
/// </summary>
[XmlRoot(Espacio de nombres = "Deps.AjaxBaseWebpart")]
clase abstracta pública AjaxBaseWebpart: Microsoft.SharePoint.WebPartPages.WebPart
{
/*
* La idea y el código detrás de este elemento web base se tomaron de la publicación del blog de Eric en:
* http://www.capdes.com/2007/02/ajaxbasepart_easy_aspnet_20_aj.html
* Esto básicamente gestiona la presencia y configuración del ScriptManager.
* que es requerido por las extensiones ASP.net ajax para manejar devoluciones de datos, etc. Este elemento web también incluye.
* un método común para manejar errores.
*/
#region Declaraciones
cadena privada _ValidationGroupId;
resumen de validación privado _ErrorContainer;
ScriptManager privado _AjaxManager;
#endregion
#region Constructor
parte web pública AjaxBase()
{
}
#endregion
#region Métodos
/// <resumen>
/// Se utiliza para proporcionar una forma común de mostrar errores al usuario del elemento web actual.
/// </summary>
/// <param name="message">Descripción del error ocurrido.</param>
RegisterError vacío público (mensaje de cadena)
{
si (this.Controls.Contains(_ErrorContainer))
{
//esta forma de generar una identificación de control única se utiliza en algunos de los elementos web OOB
int contador único;
si (HttpContext.Current.Items["GetUniqueControlId"]! = nulo)
{
contadorúnico = (int)HttpContext.Current.Items["GetUniqueControlId"];
}
demás
{
contadorúnico = 0;
}
contador único++;
HttpContext.Current.Items["GetUniqueControlId"] = uniqueCounter;
//crea un validador personalizado para registrar el mensaje de error actual con el control ValidationSummary
CustomValidator cv = nuevo CustomValidator();
cv.ID = string.Concat("_Error_", contadorúnico);
cv.ValidationGroup = _ValidationGroupId;
cv.Display = ValidatorDisplay.None;
cv.IsValid = falso;
cv.ErrorMessage = mensaje;
this.Controls.Add(cv);
}
demás
{
//si se llama a RegisterError antes de anular CreateChildControls en AjaxBasePart, transfiera al usuario a una página de error usando SPUtility
SPUtility.TransferToErrorPage("La función CreateChildControls de AjaxBasePart no ha sido llamada. Probablemente necesites agregar "base.CreateChildControls()" en la parte superior de tu anulación de CreateChildControls.");
}
}
/// <resumen>
/// Debe llamarse para garantizar que el control ValidationSummary esté registrado en la página. Cualquier elemento web secundario deberá tener base.CreateChildControls() en la parte superior de su propia anulación de CreateChildControls.
/// </summary>
anulación protegida anulación CreateChildControls()
{
base.CreateChildControls();
si (!this.Controls.Contains(_ErrorContainer))
{
_ValidationGroupId = Guid.NewGuid().ToString();
_ErrorContainer = nuevo ValidationSummary();
_ErrorContainer.ID = "_ErrorContainer";
_ErrorContainer.ValidationGroup = _ValidationGroupId;
_ErrorContainer.BorderStyle = BorderStyle.Solid;
_ErrorContainer.BorderWidth = Unidad.Pixel(3);
_ErrorContainer.BorderColor = Color.Rojo;
this.Controls.Add(_ErrorContainer);
}
}
#endregion
#region Eventos
/// <resumen>
/// Oninit se activa antes de cargar la página. Las modificaciones a la página que son necesarias para admitir Ajax se realizan aquí.
/// </summary>
anulación protegida anulación OnInit (EventArgs e)
{
base.OnInit(e);
//obtiene el ScriptManager existente si existe en la página
_AjaxManager = ScriptManager.GetCurrent (esta.Página)
si (_AjaxManager == nulo)
{
//crea un nuevo ScriptManager y EnablePartialRendering
_AjaxManager = nuevo ScriptManager();
_AjaxManager.EnablePartialRendering = true;
// Soluciona el problema con las devoluciones de datos y las acciones de formulario (DevDiv 55525)
Page.ClientScript.RegisterStartupScript(typeof(AjaxBaseWebpart), this.ID, "_spOriginalFormAction = document.forms[0].action;", true);
//etiqueta:"form" att:"onsubmit" val:"return _spFormOnSubmitWrapper( )" bloquea las devoluciones de datos asíncronas después de la primera
//no llamar a "_spFormOnSubmitWrapper()" rompe todas las devoluciones de datos
//devolver verdadero todo el tiempo, de alguna manera frustra el propósito de _spFormOnSubmitWrapper() que es bloquear devoluciones de datos repetitivas, pero permite que las extensiones MS AJAX funcionen correctamente
//es un truco que, con suerte, tendrá un efecto mínimo
si (esta.Página.Forma! = nulo)
{
cadena formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
if (!string.IsNullOrEmpty(formOnSubmitAtt) && formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
//agrega ScriptManager como primer control en Page.Form
//No creo que esto realmente importe, pero lo hice para ser coherente con la forma en que se supone que debes colocar el ScriptManager cuando se usa de forma declarada.
esta.Página.Form.Controls.AddAt(0, _AjaxManager);
}
}
}
#endregion
#region Propiedades
/// <resumen>
/// Expone el administrador de secuencias de comandos de la página. El valor no se establece hasta después de OnInit.
/// </summary>
[WebPartStorage(Almacenamiento.Ninguno)]
ScriptManager público AjaxManager
{
obtener {return _AjaxManager}
establecer { _AjaxManager = valor }
}
#regiónfinal
}
Durante el desarrollo, siempre que herede este WebPart, puede agregar UpdatePanel y agregar otros controles en él.