Hi all

Some days back I was working with update panels and I created a simple application with multiple update panels on my page. Update panels were fetching data from a third part content management system, so sending a request, fetching and displaying the data was not a tricky part of the application but that used to take around 30 to 40 seconds per request.

Initially It was good but later when we customized our application to allow user to add multiple update panels on 1 page, we got stuck with performance issues, when user tried to load a page it used to take 1 or 2 minutes to complete page output.

I searched a lot to find out the way to improve the page performance, I got the idea of lazy loading but that worked well if there was only 1 update panel on the page. After spending lot of time, finally I figured out the lazy loading implementation with unlimited number of update panels, so in ideal situation a web page loads immediately without any third party call and after page load is completed it execute update panel refresh calls from JavaScript and shows a progress bar when update panel is loading the data. So if you have n number of update panels placed on your web page, the update panel placed at first position will start loading and after that 2nd panel load will start then 3rd and so on.

So for the clear understanding of this concept I am creating a user control and that user controls has 1 update panel and some other content controls, I will drop the user control on my page 4 times, so there will be 4 update panels rendered.

Here is the sample script for user control

<asp:UpdatePanel
ID=”upUpdatePanel” runat=”server” UpdateMode=”Conditional” OnPreRender=”upUpdatePanel_PreRender”>

<ContentTemplate><asp:LinkButtonID=”LinkButton1″ runat=”server” Enabled=”false” ForeColor=”Black”Font-Bold=”true” Font-Size=”Large” onclick=”LinkButton1_Click”>LinkButton disabled so far</asp:LinkButton>

<br /><br />

<asp:LabelID=”Label2″ runat=”server” Text=”Label”></asp:Label><asp:HiddenFieldID=”HiddenField1″ runat=”server”/>

<asp:GridView
ID=”GridView1″ runat=”server” PageSize=”3″ AllowPaging=”True” OnPageIndexChanging=”GridView1_PageIndexChanging”>

</asp:GridView>

</ContentTemplate>

</asp:UpdatePanel>

<asp:UpdateProgress
ID=”updProgressTab” runat=”server” AssociatedUpdatePanelID=”upUpdatePanel”>

<ProgressTemplate><divstyle=”position: relative; top: 50%; text-align: center;”>

<asp:ImageID=”imgLoading1″ runat=”server” ImageUrl=”simple.gif” Width=”34px” Height=”30px”/>Refreshing…

</div>

</ProgressTemplate>

</asp:UpdateProgress>

Note : update panel’s update mode is “conditional” and I have registered on_PreRender event of the update panel.

For on_preRender I have implemented this logic :

protected
void upUpdatePanel_PreRender(object sender, EventArgs e)

{


string eventTarget = Request.Params[“__EVENTTARGET”] as
string;


if (string.IsNullOrEmpty(eventTarget) == false)

{


if (eventTarget.StartsWith(this.ID))

{

System.Threading.Thread.Sleep(2000);

LinkButton1.Enabled = true;

LinkButton1.Text = “Enabled Now”;


this.Label2.Text = DateTime.Now.ToString();

BindGrid1();

}

}

}

So I guess nothing special in the code logic, I am just trying to load a grid with hard coded values and with 2 second time interval.

So here is the tricky and most important part of the topic

StringBuilder sb = new
StringBuilder();

sb.Append(“var loopCounter = -1;”);

sb.Append(“function pageLoad(sender, e) {“);

sb.Append(“if (!e.get_isPartialLoad()) {“);

sb.Append(“var refreshPanels = $(\”[id*=\” + \”upUpdatePanel\” + \”]\”);”);

sb.Append(“Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);”);

sb.Append(“var panel = refreshPanels[++loopCounter];”);

sb.Append(“__doPostBack(panel.id, ‘1’);”);

sb.Append(“}function EndRequestHandler() {“);

sb.Append(“var panel = refreshPanels[++loopCounter];”);

sb.Append(“if (panel==null) {“);

sb.Append(“Sys.WebForms.PageRequestManager.getInstance().remove_endRequest(EndRequestHandler);”);

sb.Append(“}”);

sb.Append(“else {“);

sb.Append(“__doPostBack(panel.id, ‘2’);}}”);

sb.Append(“}”);

Page.ClientScript.RegisterClientScriptBlock(typeof(Page), “MYScript”, sb.ToString(), true);

Let me explain in detail.

  • First thing you need to know is that this will be rendered from controls load event
  • I am calling some script after page load event.
  • $(\”[id*=\” + \”upUpdatePanel\” + \”]\”);”)” this part is basically a JQuery selector that selects all divs having id “upUpdatePanel”, which is id of my update panel.
  • After that I am registering an end request event handler, that will be raised when update panel load request is completed.
  • I am looping through all panels and calling __doPostBack of each update panel. __doPostBack will call “upUpdatePanel_PreRender” event.
  • In EndRequestHsndler I am checking if there is another update panel remaining then call its __doPostBack otherwise simple remove end request event handler.

In my page I have dropped 4 user controls

<table
border=”0″ cellpadding=”0″ cellspacing=”0″ width=”100%”>

<tr><td

style=”width: 50%”>

<uc1:WebUserControl1ID=”WebUserControl11″ runat=”server”/>

</td>

<tdstyle=”width: 50%”>

<uc1:WebUserControl1ID=”WebUserControl12″ runat=”server”/>

</td>

</tr>

<tr>

<tdstyle=”width: 50%”>

<uc1:WebUserControl1ID=”WebUserControl13″ runat=”server”/>

</td>

<tdstyle=”width: 50%”><uc1:WebUserControl1ID=”WebUserControl14″ runat=”server”

/>

</td>

</tr>

</table>

This shows page output like


In above screen you can see first panel is being refreshed.


Now first panel has been loaded and now second panel is being refreshed. Same for 3rd and fourth



http://www.4shared.com/folder/Ryz_jgeH/Lazy_Loading.html

you can download code form above link and off course leave a comment if you did like my effort 🙂 

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.