VS 2005


I have excerpted a good article on page methods technique, hope fully you will take advantage of it.

This article shows you how to use ASP.NET AJAX PageMethods to perform Create, Read, Update and Delete (CRUD) operations with an HTML table. Here HTML table acts as a light-weight DataGrid.

Inorder to make PageMethods work, following things need to be done:

  1. ScriptManager should be added to your ASPX page.
  2. EnablePageMethods property of the ScriptManager should be set to true.
  3. System.Web.Services namespace should be added as reference on your codebehind class.
  4. Page Methods on your code-behind should be decorated with [WebMethod] attribute.

First let us start with Read.

As mentioned above, add a ScriptManager and set its ‘EnablePageMethods’ property to true. Add an HTML button and an onclick handler to it, and then add an HTML table with thead, tbody and tfoot. Since the HTML table will be referenced from javascript, add id to the table and its body. Here, only HTML tags/controls are used because, server side controls cannot be referenced in PageMethods.


Your ASPX page should look something like this.

<body>

<form id=”form1″ runat=”server”>

<asp:ScriptManager ID=”ScriptManager1″ runat=”server” EnablePageMethods =”true” ></asp:ScriptManager>

<%–This click event handles loading data from the database–%>

<input id=”btn_load” type=”button” value=”Load” onclick = “LoadData()” />

<br /><br />

<div>

<table style=” height: 100%; border: solid 1px #000″ cellpadding=”0″ cellspacing=”1″ id=”tbl_grid” border = “1”>

<thead style = “background-color: #666; color: #fff”>

<tr>

<td style=”width: 100px;”>

Column1

</td>

<td style=”width: 500px;”>

Column2

</td>

<td style=”width: 150px;”>

Edit

</td>

</tr>

</thead>

<tbody id=”tbody_grid”>

</tbody>

<tfoot>

<tr>

<td style=”width: 100px;”>

<input id=”txt_addcol1″ style =”width: 30px” type=”text” />

</td>

<td style=”width: 500px;”>

<input id=”txt_addcol2″ type=”text”  style =”width: 300px” />

</td>

<td style=”width: 150px;”>

<%–This click event handles adding data to the database–%>

<input id=”btn_add” type=”button” onclick = “Add()” value=”Add” />

</td>

</tr>

</tfoot>

</table>

</div>

</form>

</body>

Now add your JavaScript function to load data from the database using PageMethods. PageMethod call should always have a success handler (this will be executed if the page method is executed successfully) and an exception handler (this will be executed if an exception is thrown). Say suppose we added ‘GetData()’ as the page method on the code behind, our javascript will be PageMethods.GetData(SuccessHandler, ExceptionHandler). Just for understanding, I have named the success and exception handler appropriately, you can name them as you wish. In case, the page methods takes parameters, you can add like PageMethods.GetData(param1, param2, SuccessHandler, ExceptionHandler).

Page methods should be decorated with [WebMethod] attribute and should be declared as static. Its signature shoul look something like this:

[WebMethod]

public static string GetData()



Page method to return data to javascript.

public partial class AJAXGrid : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

}

[WebMethod]

public static IEnumerable<MyEntity> GetData()

{

try

{

Data fetch part should go here

// used List, as collections are serializable. See below for MyEntity class

List<MyEntity> MyEntities = new List<MyEntity>();

MyEntities.Add(“1”, “abc”);

MyEntities.Add(“2”, “xyz”);

MyEntities.Add(“3”, “pqr”);

MyEntities.Add(“4”, “mno”);

return MyEntities;

}

catch(Exception ex)

{

throw ex;

}

}
}

MyEntity class

public class MyEntity

{

private string _Column1;

public string Column1

{

get { return _Column1; }

set { _Column1 = value; }

}

private string _Column2;

public string Column2

{

get { return _Column2; }

set { _Column2 = value; }

}

public MyEntity(string sCol1, string sCol2)

{

_Column1 = sCol1;

_Column2 = sCol2;

}

}

Javascript function that calls page method and populates the HTML table

<script type =”text/javascript” language = “javascript “>

//Loading Data

// Handles btn_load click event

function LoadData() {

// If data was fetched successfully, SuccessHandler will be called; else, ExceptionHandler

PageMethods.GetData(SuccessHandler, ExceptionHandler);

// Incase parameters need to be passed to PageMethods, you can do like this PageMethods.GetData(param1, param2, SuccessHandler, ExceptionHandler)

}

// After fetching the data successfully

function SuccessHandler(result) {

var tbody = $get(“tbody_grid”);

// clear the table

for (var j = tbody.rows.length; j > 0; j–) {

tbody.deleteRow(j – 1);

}

// populate the table

for (var i = 0; i < result.length; i++) {

//two columns fetched from database are sent as parameters

AddRow(result[i].Column1, result[i].Column2);

}

return true;

}

// Edit and Delete buttons are added to the rows

function AddRow(col1, col2) {

var tbody = $get(“tbody_grid”);

var row = document.createElement(“tr”)

var td1 = document.createElement(“td”)

td1.innerText = col1;

var td2 = document.createElement(“td”);

td2.innerText = col2;

var td3 = document.createElement(“td”);

// add buttons

var btnEdit = document.createElement(‘input’);

btnEdit.setAttribute(‘type’, ‘button’);

btnEdit.setAttribute(‘name’, ‘Edit’);

btnEdit.setAttribute(‘value’, ‘Edit’);

// first parentNode represents <td> and the second represents <tr>

btnEdit.onclick = function() { Edit(this.parentNode.parentNode); };

var btnDelete = document.createElement(‘input’);

btnDelete.setAttribute(‘type’, ‘button’);

btnDelete.setAttribute(‘name’, ‘Delete’);

btnDelete.setAttribute(‘value’, ‘Delete’);

btnDelete.onclick = function() { DeleteRow(this.parentNode.parentNode); };

td3.appendChild(btnEdit);

td3.appendChild(btnDelete);

row.appendChild(td1);

row.appendChild(td2);

row.appendChild(td3);

tbody.appendChild(row);

}

// Handles exception

function ExceptionHandler(result) {

}

After populating the HTML table



Javascript functions to handle Edit, Update, Delete and Insert:


Editing Data

//  this function handles edit button click

function Edit(row) {

var col1 = row.childNodes[0].innerText;

var col2 = row.childNodes[1].innerText;

// populates values in textboxes and displays Update and Cancel buttons

var editableRow = document.createElement(“tr”)

var td1 = document.createElement(“td”)

var txtBox1 = document.createElement(‘input’);

txtBox1.setAttribute(‘type’, ‘text’);

txtBox1.setAttribute(‘name’, ‘col1’);

txtBox1.setAttribute(‘value’, col1);

txtBox1.setAttribute(‘width’, 30);

td1.appendChild(txtBox1);

var td2 = document.createElement(“td”);

var txtBox2 = document.createElement(‘input’);

txtBox2.setAttribute(‘width’, 300);

txtBox2.setAttribute(‘type’, ‘text’);

txtBox2.setAttribute(‘name’, ‘col1’);

txtBox2.setAttribute(‘value’, col2);

td2.appendChild(txtBox2);

var td3 = document.createElement(“td”);

var btnUpdate = document.createElement(‘input’);

btnUpdate.setAttribute(‘type’, ‘button’);

btnUpdate.setAttribute(‘name’, ‘Update’);

btnUpdate.setAttribute(‘value’, ‘Update’);

btnUpdate.onclick = function() { Update(this.parentNode.parentNode); };

var btnCancel = document.createElement(‘input’);

btnCancel.setAttribute(‘type’, ‘button’);

btnCancel.setAttribute(‘name’, ‘Cancel’);

btnCancel.setAttribute(‘value’, ‘Cancel’);

btnCancel.onclick = function() { Cancel(this.parentNode.parentNode); };

td3.appendChild(btnUpdate);

td3.appendChild(btnCancel);

editableRow.appendChild(td1);

editableRow.appendChild(td2);

editableRow.appendChild(td3);

row.parentNode.replaceChild(editableRow, row);

}

After edit button click

Updating Data

//  this function handles update button click

function Update(row) {

// fetches values entered in the textboxes

// first childNode represent <td> inside <tr> and second childNode represents textbox

var col1 = row.childNodes[0].childNodes[0].value;

var col2 = row.childNodes[1].childNodes[0].value;

// values sent to server

PageMethods.UpdateData(col1, col2, UpdateSuccess(row), ExceptionHandler);

}

// After updating the values successfully

function UpdateSuccess(row) {

var col1 = row.childNodes[0].childNodes[0].value;

var col2 = row.childNodes[1].childNodes[0].value;

var editableRow = document.createElement(“tr”)

var td1 = document.createElement(“td”)

td1.innerText = col1;

var td2 = document.createElement(“td”);

td2.innerText = col2;

var td3 = document.createElement(“td”);

var btnEdit = document.createElement(‘input’);

btnEdit.setAttribute(‘type’, ‘button’);

btnEdit.setAttribute(‘name’, ‘Edit’);

btnEdit.setAttribute(‘value’, ‘Edit’);

btnEdit.onclick = function() { Edit(this.parentNode.parentNode); };

var btnDelete = document.createElement(‘input’);

btnDelete.setAttribute(‘type’, ‘button’);

btnDelete.setAttribute(‘name’, ‘Delete’);

btnDelete.setAttribute(‘value’, ‘Delete’);

btnDelete.onclick = function() { DeleteRow(this.parentNode.parentNode); };

td3.appendChild(btnEdit);

td3.appendChild(btnDelete);

editableRow.appendChild(td1);

editableRow.appendChild(td2);

editableRow.appendChild(td3);

row.parentNode.replaceChild(editableRow, row);

}

// this function handles cancel button click

function Cancel(row) {

// values are again populated in labels instead of textboxes

var col1 = row.childNodes[0].childNodes[0].value;

var col2 = row.childNodes[1].childNodes[0].value;

var editableRow = document.createElement(“tr”)

var td1 = document.createElement(“td”)

td1.innerText = col1;

var td2 = document.createElement(“td”);

td2.innerText = col2;

var td3 = document.createElement(“td”);

var btnEdit = document.createElement(‘input’);

btnEdit.setAttribute(‘type’, ‘button’);

btnEdit.setAttribute(‘name’, ‘Edit’);

btnEdit.setAttribute(‘value’, ‘Edit’);

btnEdit.onclick = function() { Edit(this.parentNode.parentNode); };

var btnDelete = document.createElement(‘input’);

btnDelete.setAttribute(‘type’, ‘button’);

btnDelete.setAttribute(‘name’, ‘Delete’);

btnDelete.setAttribute(‘value’, ‘Delete’);

btnDelete.onclick = function() { DeleteRow(this.parentNode.parentNode); };

td3.appendChild(btnEdit);

td3.appendChild(btnDelete);

editableRow.appendChild(td1);

editableRow.appendChild(td2);

editableRow.appendChild(td3);

row.parentNode.replaceChild(editableRow, row);

}

//  this function handles ‘add’ button click

function Add() {

var col1 = $get(“txt_addcol1”).value;

var col2 = $get(“txt_addcol2”).value;

// data sent to the database

PageMethods.InsertData(col1, col2, AddSuccess(col1, col2), ExceptionHandler);

}

// After adding the data successfully

function AddSuccess(col1, col2) {

// add the values to the table

AddRow(col1, col2);

// clear the textboxes in the footer

$get(“txt_addcol1”).value = “”;

$get(“txt_addcol2”).value = “”;

}

Deleting Data

// this function handles delete button click

function DeleteRow(row) {

var col1 = row.childNodes[0].innerText;

// delete from the database

PageMethods.DeleteData(col1, DeleteSuccess(row), ExceptionHandler);

}

function DeleteSuccess(row) {

// delete the row from the table

var tbody = $get(“tbody_grid”);

tbody.removeChild(row);

}

</script>

Page methods to handle Edit, Update, Delete and Insert:

[WebMethod]

public static void UpdateData(string sCol1, string sCol2)

{

try

{

Data update part should go here

}

catch(Exception ex)

{

throw ex;

}

}

[WebMethod]

public static void InsertData(string sCol1, string sCol2)

{

try

{

Data insert part should go here

}

catch(Exception ex)

{

throw ex;

}

}

[WebMethod]

public static void DeleteData(string sCol1)

{

try

{

Data delete part should go here

}

catch (Exception ex)

{

throw ex;

}

}

}

We can add paging and sorting too.


This code has been tested in IE7+, Firefox, Chrome and Safari.

Some of the limitations in using ASP.NET AJAX PageMethods:

1.       We can’t access asp.net server controls (like TextBox control) in the WebMethod directly as we normally access in the server side methods.

2.       We can’t access any variable declared in the code behind.

Advantage: PageMethods is a simple lightweight way to submit/fetch data to the server using ASP.NET AJAX. This doesn’t submit whole page data to the server and also as opposed to the ASP.NET AJAX call back this doesn’t even fire the Page_Load and other Page events of the code behind page

Enabling AJAX in SharePoint applications was a really tough job, I spent a lot of time to get it work and now I want to save time of others developers. Just follow me on the steps and at the end we will be able to add a web part with AJAX functionality.

I am dividing my post in 2 steps

STEP 1 : in step 1 I will do the necessary web.config modifications. I am pulling all these settings through “FeatureInstalled” event of a feature with Web Application level scope, have a look at the following code

<?xml version=”1.0″ encoding=”utf-8″ ?>

<Feature Id=”c9cf98e2-cc0e-4464-914c-4c974ec2e133″

Scope=”Web”

Title=”UI Feature ”

Description=”This feature enables the UI functionality within a SharePoint Site.”

Version=”1.0.0.0″

Creator=”Shafaqat Ali”

SolutionId=”62298653-d7de-4b56-b50f-5df3d116e590″

ImageUrl=””

ImageUrlAltText=”My Feature Icon”

Hidden=”FALSE”

ActivateOnDefault=”FALSE”

AlwaysForceInstall=”FALSE”

AutoActivateInCentralAdmin=”FALSE”

RequireResources=”FALSE”

DefaultResourceFile=”MyResourceFile”

ReceiverAssembly=”UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6669f18c4e55eb20″

ReceiverClass=”UI.UIFeatureReceiver”

xmlns=”http://schemas.microsoft.com/sharepoint/”&gt;

<ElementManifests>

<ElementManifest Location=”Elements.xml” />

</ElementManifests>

</Feature>

Feature receiver code behind file, lengthy code you can copy paste it.

/***********************************************************************************

public override void FeatureInstalled(SPFeatureReceiverProperties properties) {

#region Extend the SharePoint web.config file, which is typically found in a directory with the following structure

//For ASP.NET 2.0 AJAX Extensions

//1. Add the following <sectionGroup> elements within the <configSections> element.

SPWebConfigModification sectionGroup = this.GetConfigurationSettingsforAJAX();

//2. Add the following controls declaration within the <pages> element, which is located within the <system.web> element.

SPWebConfigModification controlInPages = this.GetControlInPagesSettings();

//3. Add the following assembly declaration within the <assemblies> element.

SPWebConfigModification assembly1 = this.GetAssembly1Settings();

//4. Add the following verb handlers within the <httpHandlers> element.

SPWebConfigModification verb1 = this.GetVerb1Settings();

SPWebConfigModification verb2 = this.GetVerb2Settings();

SPWebConfigModification verb3 = this.GetVerb3Settings();

SPWebConfigModification verb4 = this.GetVerb4Settings();

//5. Add the following script module handler within the <httpModules> element.

SPWebConfigModification scriptmodulehandler = this.GetScriptModuleSettings();

//6.  Add the following safe control entry within the <SafeControls> element, which is located within the <SharePoint> element.

SPWebConfigModification safecontrol = this.GetSafeControlsSettings();

//7. Add the following scripting web service handlers within the <configuration> element.

SPWebConfigModification systemwebextensions = this.GetWebExtensionsSettings();

// These settings are required for AJAX implemenation

SPWebConfigModification systemwebServer = this.GetSystemWebServerSettings();

#endregion

//System.Diagnostics.Debug.Assert(false);

// Iterate through all the Web Applications and apply the changes

SPWebApplicationCollection webAppCollection = SPWebService.ContentService.WebApplications;

System.Collections.IEnumerator enumerator = webAppCollection.GetEnumerator();

while (enumerator.MoveNext())

{

SPWebApplication webApplication = (SPWebApplication)enumerator.Current;

//SPWeb web = properties.Feature.Parent;

webApplication.WebConfigModifications.Add(sectionGroup); webApplication.WebConfigModifications.Add(controlInPages);

webApplication.WebConfigModifications.Add(assembly1);

webApplication.WebConfigModifications.Add(verb2);

webApplication.WebConfigModifications.Add(verb3);

webApplication.WebConfigModifications.Add(verb4);

webApplication.WebConfigModifications.Add(scriptmodulehandler);

webApplication.WebConfigModifications.Add(safecontrol);

webApplication.WebConfigModifications.Add(systemwebextensions);

webApplication.WebConfigModifications.Add(systemwebServer);

webApplication.Update(true);

webApplication.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

}

// We also want to propagate these web.config changes across the farm

//SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

}

private SPWebConfigModification GetConfigurationSettingsforAJAX()

{

SPWebConfigModification sectionGroup = new SPWebConfigModification();

sectionGroup.Path = “configuration/configSections”;

sectionGroup.Name = “sectionGroup[@name=’system.web.extensions’][@type=’System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′]”;

sectionGroup.Sequence = 4;

sectionGroup.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

sectionGroup.Value = “<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=’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>”;

return sectionGroup;

}

private SPWebConfigModification GetControlInPagesSettings()

{

SPWebConfigModification controlInPages = new SPWebConfigModification();

controlInPages.Path = “configuration/system.web/pages”;

controlInPages.Name = “controls”;

controlInPages.Sequence = 6;

controlInPages.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

controlInPages.Value = “<controls><add tagPrefix=’asp’ namespace=’System.Web.UI’ assembly=’System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′ /></controls>”;

return controlInPages;

}

private SPWebConfigModification GetAssembly1Settings()

{

SPWebConfigModification assembly1 = new SPWebConfigModification();

assembly1.Path = “configuration/system.web/compilation/assemblies”;

assembly1.Name = “add[@assembly=’System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′]”;

assembly1.Sequence = 7;

assembly1.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

assembly1.Value = “<add assembly=’System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′ />”;

return assembly1;

}

private SPWebConfigModification GetVerb1Settings()

{

SPWebConfigModification verb1 = new SPWebConfigModification();

verb1.Path = “configuration/system.web/httpHandlers”;

verb1.Name = “remove[@verb=’*’][@path=’*.asmx’]”;

verb1.Sequence = 8;

verb1.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

verb1.Value = “<!–<remove verb=’*’ path=’*.asmx’ />–>”;

return verb1;

}

private SPWebConfigModification GetVerb2Settings()

{

SPWebConfigModification verb2 = new SPWebConfigModification();

verb2.Path = “configuration/system.web/httpHandlers”;

verb2.Name = “add[@verb=’*’][@path=’*.asmx’][@validate=’false’][@type=’System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′]”;

verb2.Sequence = 9;

verb2.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

verb2.Value = “<add verb=’*’ path=’*.asmx’ validate=’false’ type=’System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′ />”;

return verb2;

}

private SPWebConfigModification GetVerb3Settings()

{

SPWebConfigModification verb3 = new SPWebConfigModification();

verb3.Path = “configuration/system.web/httpHandlers”;

verb3.Name = “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′]”;

verb3.Sequence = 10;

verb3.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

verb3.Value = “<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′ />”;

return verb3;

}

private SPWebConfigModification GetVerb4Settings()

{

SPWebConfigModification verb4 = new SPWebConfigModification();

verb4.Path = “configuration/system.web/httpHandlers”;

verb4.Name = “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’]”;

verb4.Sequence = 11;

verb4.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

verb4.Value = “<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’ />”;

return verb4;

}

private SPWebConfigModification GetScriptModuleSettings()

{

SPWebConfigModification scriptmodulehandler = new SPWebConfigModification();

scriptmodulehandler.Path = “configuration/system.web/httpModules”;

scriptmodulehandler.Name = “add[@name=’ScriptModule’][@type=’System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′]”;

scriptmodulehandler.Sequence = 12;

scriptmodulehandler.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

scriptmodulehandler.Value = “<add name=’ScriptModule’ type=’System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′ />”;

return scriptmodulehandler;

}

private SPWebConfigModification GetSafeControlsSettings()

{

SPWebConfigModification safecontrol = new SPWebConfigModification();

safecontrol.Path = “configuration/SharePoint/SafeControls”;

safecontrol.Name = “SafeControl[@Assembly=’System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′][@Namespace=’System.Web.UI’][@TypeName=’*’][@Safe=’True’]”;

safecontrol.Sequence = 13;

safecontrol.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

safecontrol.Value = “<SafeControl Assembly=’System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′ Namespace=’System.Web.UI’ TypeName=’*’ Safe=’True’ />”;

return safecontrol;

}

private SPWebConfigModification GetWebExtensionsSettings()

{

SPWebConfigModification systemwebextensions = new SPWebConfigModification();

systemwebextensions.Path = “configuration”;

systemwebextensions.Name = “system.web.extensions”;

systemwebextensions.Sequence = 14;

systemwebextensions.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

systemwebextensions.Value = “<system.web.extensions><scripting><webServices></webServices></scripting></system.web.extensions>”;

return systemwebextensions;

}

private SPWebConfigModification GetSystemWebServerSettings()

{

SPWebConfigModification systemwebServer = new SPWebConfigModification();

systemwebServer.Path = “configuration”;

systemwebServer.Name = “system.webServer”;

systemwebServer.Sequence = 15;

systemwebServer.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

systemwebServer.Value = “<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>”;

return systemwebServer;

}

***********************************************************************************/

Step 1 is complete, all required settings for AJAX functionality have been implemented, you can check AJAX functionality by adding a simple logic on any page your sharepoint site.

Let’s move to step 2

STEP2

create a simple class say “MyFirstWebPart” and inherit it form “Microsoft.SharePoint.WebPartPages.WebPart” class

public class MyFirstWebPart: Microsoft.SharePoint.WebPartPages.WebPart

{

private string imagepath;

[DefaultValue(“”), WebBrowsable(true), Category(“ProgressTemplate”), Personalizable(PersonalizationScope.Shared)]

public string ImagePath

{

get { return imagepath; }

set { imagepath = value; }

}

private string disptext;

[DefaultValue(“”), WebBrowsable(true), Category(“ProgressTemplate”), Personalizable(PersonalizationScope.Shared)]

public string DisplayText

{

get { return disptext; }

set { disptext = value; }

}

protected override void CreateChildControls()

{

base.CreateChildControls();

UpdatePanel updatePanel1 = new UpdatePanel();

updatePanel1.ID = “udpItemListingWebPart”;

updatePanel1.UpdateMode = UpdatePanelUpdateMode.Conditional;

UpdateProgress updateProgress1 = new UpdateProgress();

updateProgress1.AssociatedUpdatePanelID = “udpItemListingWebPart”;

updateProgress1.ProgressTemplate = new ProgressTemplate(ImagePath, DisplayText);

Button button1 = new Button();

button1.ID = “btnClick”;

button1.Text = “Update”;

button1.Click += new EventHandler(button1_Click);

Label label1 = new Label();

label1.ID = “lblShowTime”;

label1.Text = string.Format(“Updated at: {0} “, DateTime.Now.ToLongTimeString());

updatePanel1.ContentTemplateContainer.Controls.Add(label1);

updatePanel1.ContentTemplateContainer.Controls.Add(button1);

this.Controls.Add(updateProgress1);

ScriptManager sc = new ScriptManager();

this.Controls.AddAt(0, sc);

this.Controls.Add(updatePanel1);

}

void button1_Click(object sender, EventArgs e)

{

//this.label1.Text = string.Format(“Updated at: {0} “, DateTime.Now.ToLongTimeString());

}

protected override void Render(HtmlTextWriter writer)

{

base.Render(writer);

if (!this.Page.IsAsync)

{

string script = “”;

script = @”

var ITEMLISTINGBUTTONID;

with(Sys.WebForms.PageRequestManager.getInstance()){

add_beginRequest(onBeginRequest);

add_endRequest(onEndRequest);

}

function onBeginRequest(sender, args){

ITEMLISTINGBUTTONID = args.get_postBackElement().id;

$get(ITEMLISTINGBUTTONID).parentElement.style.display = ‘none’;

}

function onEndRequest(sender, args){

$get(ITEMLISTINGBUTTONID).parentElement.style.display = ”;

}

“;

this.Page.ClientScript.RegisterStartupScript(this.GetType(), “HideSimpleAJAXWebPartUDP”, script, true);

}

}

}

public class ProgressTemplate : ITemplate

{

private string imagepath;

public string ImagePath

{

get { return imagepath; }

set { imagepath = value; }

}

private string disptext;

public string DisplayText

{

get { return disptext; }

set { disptext = value; }

}

public ProgressTemplate(string imagePath, string displayText)

{

ImagePath = imagePath;

DisplayText = displayText;

}

public void InstantiateIn(Control container)

{

Image img = new Image();

img.ImageUrl = SPContext.Current.Site.Url + “/” + ImagePath;

Label lbl = new Label();

lbl.Text = DisplayText;

container.Controls.Add(img);

container.Controls.Add(lbl);

}

}

Now add your assembly to safe controls list

<SafeControl Assembly=”YourAssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6669f18c4e55eb20″ Namespace=”UI.Code” TypeName=”*” Safe=”True” />

Refresh the page you will see this screen

1

I know the code is very complex, try at your end, if you find any problem or stuck anywhere do contact me.

Debugging the SharePoint Timer job was really a tough job for me, i searched on the web and found so many solutions but they did not work at my system (i dont know why). Finally i did a trick to debugg the timer service, i added the following line of code in the timer service job where you want to have a break point:

1

after compiling the solution and restarting my timer service it came with the following popup options :

2

  • Abort– means you want to stop timer service instance
  • Retry- means you want to debugg the code
  • ignore- means ignore this message and continue the execution of the code

for debugging i selected retry and it opened another screen

3

selected new instance of CLR debugger, it showed the following screen

4

after pressing F10 two times it did enable debugging like this

5

here i did normal debugging by pressing F10 and F11 keys

6

you can also use breakpoints here

7

hope this helps

if you think this is helpfull , dont forget to leave a comment.