Primero se necesita configurar Sharepoint para soportar Ajax .Net. Para esto hay que seguir los siguientes pasos:
1. Instalar Microsoft Framework 3.5.0.0 en el servidor
2. Modificar el web.config
a. Agregar lo siguiente dentro de <configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
b. Agregar lo siguiente dentro de <pages>
<controls>
<add tagPrefix="ajax" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="ajax" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
c. Agregar lo siguiente dentro de <compilation><assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
d. Agregar lo siguiente dentro de <httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
e. Agregar lo siguiente dentro de <httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
f. Agregar lo siguiente dentro de <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>
<remove name="ScriptModule"/>
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>
<validation validateIntegratedModeConfiguration="false"/>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<remove name="ScriptHandlerFactory"/>
<remove name="ScriptHandlerFactoryAppServices"/>
<remove name="ScriptResource"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.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=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</handlers>
</system.webServer>
g. Agregar lo siguiente dentro de <SafeControls>
<SafeControl Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TypeName="*" Safe="True" />
3. Modificar la masterpage default.master que se encuentra en :
“C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\GLOBAL”
a. Agregar lo siguiente para habilitar los controles en todas las paginas
<asp:ScriptManager runat="server" ID="ScriptManagerControles">
</asp:ScriptManager>
Deberia quedar en el siguiente lugar:
<form runat="server" onsubmit="return _spFormOnSubmitWrapper();">
<WebPartPages:SPWebPartManager id="m" runat="Server" />
<asp:ScriptManager runat="server" ID="ScriptManagerControles">
</asp:ScriptManager>
<TABLE class="ms-main" CELLPADDING=0 CELLSPACING=0 BORDER=0
WIDTH="100%" HEIGHT="100%">
Mostramos un ejemplo para utilizar los controles de Ajax.Net en un WebPart de Sharepoint. En el Anexo 1: Implementando Ajax.Net podemos ver la descripción completa de cada control que provee Ajax.Net
1. Referenciar en el proyecto a System.Web.Extensions (de Ajax)
2. Código del WebPart:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
namespace WebPartTestAJAXNet
{
public class WebPartTestControles: System.Web.UI.WebControls.WebParts.WebPart
{
// ASP.NET Controls declaration
private Label label;
private Label label2;
private Label label3;
private TextBox textBox1;
private TextBox textBox2;
// ASP.NET AJAX Controls declaration
protected UpdatePanel updatePanel;
protected UpdateProgress updateProgress;
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<Table>");
writer.Write("<tr><td>");
updatePanel.RenderControl(writer);
writer.Write("</td></tr><tr><td>");
updateProgress.RenderControl(writer);
writer.Write("</td></tr>");
writer.Write("</Table>");
}
protected override void CreateChildControls()
{
// Fix Form Action
this.FixFormAction();
updatePanel = new UpdatePanel();
updateProgress = new UpdateProgress();
updatePanel.ID = "_UpdatePanel";
updateProgress.ID = "_UpdateProgress";
//Create Update Progress Template
string templateHTML =
"<div>Loading...</div>";
updateProgress.ProgressTemplate = new ProgressTemplate(templateHTML);
updateProgress.AssociatedUpdatePanelID = updatePanel.ClientID;
updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;
this.Controls.Add(updatePanel);
this.label = new Label();
this.label2 = new Label();
this.label3 = new Label();
this.label.Text = "Enter 1st Number: ";
this.label2.Text = "Enter 2nd Number: ";
this.textBox1 = new TextBox();
this.textBox1.ID = "TextBox1";
this.textBox2 = new TextBox();
this.textBox2.ID = "TextBox2";
//Adding Controls
updatePanel.ContentTemplateContainer.Controls.Add(this.label);
updatePanel.ContentTemplateContainer.Controls.Add(this.textBox1);
updatePanel.ContentTemplateContainer.Controls.Add(new LiteralControl("<br />"));
updatePanel.ContentTemplateContainer.Controls.Add(this.label2);
updatePanel.ContentTemplateContainer.Controls.Add(this.textBox2);
updatePanel.ContentTemplateContainer.Controls.Add(new LiteralControl("<br /><br />"));
Button button = new Button();
button.Text = "Calculate";
button.Click += new EventHandler(HandleButtonClick);
updatePanel.ContentTemplateContainer.Controls.Add(button);
updatePanel.ContentTemplateContainer.Controls.Add(new LiteralControl(" "));
updatePanel.ContentTemplateContainer.Controls.Add(this.label3);
updatePanel.ContentTemplateContainer.Controls.Add(updateProgress);
}
private void HandleButtonClick(object sender, EventArgs eventArgs)
{
try
{
//Just wait to see the progress loader working
System.Threading.Thread.Sleep(2000);
this.label3.Text = Convert.ToString(int.Parse(textBox1.Text)
+ int.Parse(textBox2.Text));
}
catch (Exception ex)
{
label3.Text = "Ingrese valores validos";
}
}
//Fixing Form Action
private void FixFormAction ()
{
if (this.Page.Form != null)
{
string formOnSubmitAtt =
this.Page.Form.Attributes["onsubmit"];
if(formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] =
"_spFormOnSubmitWrapper();";
}
}
ScriptManager.RegisterStartupScript(this, typeof(WebPartTestControles), "UpdatePanelFixup", "_spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;", true);
}
}
//Class for Building progress tempales
public class ProgressTemplate : ITemplate
{
private string template;
public ProgressTemplate(string temp)
{
template = temp;
}
public void InstantiateIn(Control container)
{
LiteralControl ltr = new LiteralControl(this.template);
container.Controls.Add(ltr);
}
}
}
3. El WebPart: Suma 2 números y devuelve el resultado.
Una vez configurado Sharepoint para soportar Ajax .Net. Se deben seguir los siguientes pasos:
1. En la dll del WebPart colocar el código del servicio. No es una limitación, nos vamos a limitar a hacerlo así por prolijidad, por consistencia y mantenibilidad.
Una vez generado el WebPart, se registra como seguro.
2. Generar el archivo .asmx:
Generar un archivo .asmx físico apuntando al código del servicio que se encuentra en la dll del WebPart. El archivo debe contener la información del siguiente ejemplo (ServiceTestAjax.asmx):
<%@ WebService Language="C#" Class="WebPartTestAJAXNet.WebServiceTest01, WebPartTestAJAXNet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5" %>
3. Colocar el servicio en el servidor:
Colocar el archive .asmx en la siguiente dirección “C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\isapi\DesarrolloSHP\NombreDll\”
Si no existe el directorio “\DesarrolloSHP\NombreDll\” habrá que crearlos.
4. Para colocar la referencia en la máster del sitio. En el ejemplo anterior:
<asp:ScriptManager runat="server" ID="ScriptManagerProyecto1">
<Services>
<asp:ServiceReference Path='/sitios/desarrollo02/_VTI_BIN/DesarrolloSHP/NombreDll/ServiceTestAjax.asmx' />
</Services>
</asp:ScriptManager>