Pages

Subscribe Twitter Twitter

Friday, November 26, 2010

ASP.NET Ajax client-side framework failed to load on IIS 7.5

We upgraded an asp.net application from 2.0 to 3.5 Framework and it started throwing “ASP.NET Ajax client-side framework failed to load”. If you look the rendered code you can observe that “Sys” is undefined and hence it throws that error.

if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.');

But why this “Sys” object is undefined…. ?!!?


Well there can be many things that might be wrong to cause this issue. There can be some configuration entries missing in the web.confg or some entry might be wrong. But in our case everything was correct and still the error persisted. After a lot of search we came to know that order of handlers under system.WebServer matters….!

Just add “ScriptResource” directly below “AssemblyResourceLoader-Integrated” and it works…!

These are the entries under System.WebServer and the order is important.

<add name="AssemblyResourceLoader-Integrated" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode"/>

<add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>


This is where we found the solution: http://goo.gl/bOg9o

Hope this helps…

Thursday, September 2, 2010

jQuery Ajax in ASP.net the easy way


Using Ajax for creating better user experience on the web has become a necessity in recent times. There are multiple ways to create Ajax request and multiple frameworks are created for the same purpose.

Here is a straightforward and simple way to use jQuery ajax with ASP.Net. Ok then... Lets get going with the code :)

Fire open your Visual Studio and start a new web site by going to File>New Web Site. If you do it with VS 2010, it will add jQuery 1.4.1 framework to your project automatically; if you do it with VS 2008, download the latest jQuery framework and add it. Another approach is to refer it form the Google CDN.

Before we start Here is the UI for the example:

On the left pan I have a UL tag, with some LI elements and the last LI element is a ASP:Button control. The right pan displays the result.

Here is the script for code for the Default.aspx (Anyway i have provided the full solution for download)

$(document).ready(function () {

$('.v1').click(function () {

AjaxFetchdata('v1');

});

$('.v2').click(function () {

AjaxFetchdata('v2');

});

$('.v3').click(function () {

AjaxFetchdata('v3');

});

});



function AjaxFetchdata(clickValue) {

$.ajax({

type: "GET",

url: 'Default.aspx?id=' + clickValue.toString(),

dataType: "html",

success: AjaxSucceeded,

error: AjaxFailed

});

}



function AjaxSucceeded(result) {

if (result.toString() == '') {

$(".div-rightBody").html('

No results found

');


}

else {

$(".div-rightBody").html(result.toString());

}

}



function AjaxFailed(result) {

$(".div-rightBody").html(result);

}




Visit jQuery API Reference for the syntax of $.ajax(). You can also check VisualjQuery.

Here is the code for Default.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
if (Request.Headers["X-Requested-With"] != null && string.Compare(Request.Headers["X-Requested-With"], "XMLHttpRequest", true) == 0)
{
ProcessAjaxRequest();

}
else
{
divBody.InnerText = "Non-Ajax Response.. :(";
}
}

protected void ProcessAjaxRequest()
{
if (!string.IsNullOrEmpty(Request.QueryString["id"].ToString()))
{
string qString = Request.QueryString["id"].ToString();
if (!string.IsNullOrEmpty(qString))
{
Response.Clear();
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
HttpContext.Current.Response.ContentType = "text/HTML";
StringBuilder responseBuilder = new StringBuilder();
responseBuilder.Append("Ajax Response :)
");
switch (qString)
{
case "v1":
responseBuilder.Append("You clicked value 1");

break;
case "v2":
responseBuilder.Append("You clicked value 2");
break;
case "v3":
responseBuilder.Append("You clicked value 3");
break;
default:
responseBuilder.Append("I m sorry didn't get it properly");

break;
}
Response.Write(responseBuilder.ToString());
Response.End();
}
}
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
divBody.InnerText = "Again Non-Ajax Response.. :(";
}

That's all it takes..! Run the project and click on the left navigation items to see the result... :)

Download Code

Wednesday, August 25, 2010

Reading configurations from a file in Silverlight 3

Reading configurations from a file in Silverlight is little cumbersome. You can add app.config file to a silverlight application but after compiling the application, a compressed assembly will be created which will have the app.config also. The assembly will have .xap extension which you can change to .zip to see the contents. Now the problem is you can not modify the app.config as and when required... each time you will have to take a new build... :(

In my case I had multiple servers and each server had different values for the config keys so using the app.config was ruled out. I wanted to put my config data in a normal XML file and read it from the silverlight app. But that is not a straight forward job..! After a lot of research i came up with an approach to put an xml file in the ClientBin folder of the web application which hosts the Silverlight tool and read the xml with the help of a WebClient object.

Here is the code for the same:

WebClient configClient = new WebClient();
configClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(LoadConfigurationsHandler);
configClient.DownloadStringAsync(new Uri("customConfig.xml", UriKind.RelativeOrAbsolute));

The file customConfig.xml is put under ClientBin folder of the host application, which has the .xap file also. Because of that we need not provide a URL for the config file.

After reading the xml file, set it to a property on the App.xaml.cs, so that it can be accessed anytime during the lifetime of the application.

void LoadConfigurationsHandler(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
currentApp = (App)App.Current;
currentApp.AppConfig = e.Result;
}
else
{
MessageBox.Show("There was an unanticipated error in retrieving data from the server.", "Error", MessageBoxButton.OK);
}
}

Here the AppConfig is a string property created on the App.xaml.cs

Once this value is set, you can always obtain the config values from the AppConfig property.

currentApp = (App)App.Current;
XElement root = XDocument.Parse(currentApp.AppConfig).Element("testroot");

Hope that should be helpful for reading config files.

There is another approach on CodeProject which is slightly complicated. I felt the above method to be easier.. :)

Friday, August 13, 2010

Rendering Repeater control from code behind in asp.net

I wanted to generate the HTML response for a jQuery ajax request and bind the HTML response to a div tag. Since it was a tabular data picked from a generic list, I had to use a repeater control. But rendering the HTML response with the repeater was not so easy with repeater. After some digging down and head scratching i got it done. Here I am posting the full code so that no one else has to scratch their head if such a thing comes up.. :P

The code is not so well written and contains some dummy variable names.. :( but it serves the purpose and you can build up on the logic. The code doesn't have ajax part but only the HTML rendering from the code behind. It is just a POC anyway...

using System.Web.UI.WebControls;
using System.Web.UI;


public class Employee
{

public Employee(string name, string phone, string mail)

{
this.Name = name;
this.phone = phone;
this.mailid = mail;
}
public string Name;

public string phone;
public string mailid;
}


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

{
protected void Page_Load(object sender, EventArgs e) {


List empList = new List();


Employee emp = new Employee("amit","123","mail1");

Employee emp1 = new Employee("amit1", "1231", "mail1");

Employee emp2 = new Employee("amit2", "1232", "mail2");

Employee emp3 = new Employee("amit3", "1233", "mail3");

Employee emp4 = new Employee("amit4", "1234", "mail4");

empList.Add(emp);
empList.Add(emp1);
empList.Add(emp2);
empList.Add(emp3);
empList.Add(emp4);

Repeater testRepeater = new Repeater();

testRepeater.DataSource = empList;
testRepeater.DataBind();

foreach (RepeaterItem item in testRepeater.Items)

{
RepeaterItem it = new RepeaterItem(item.ItemIndex, ListItemType.Item);

System.Web.UI.WebControls.Label lbl = new System.Web.UI.WebControls.Label();
lbl.Text = (empList[item.ItemIndex].Name);

item.Controls.Add(lbl);

System.Web.UI.WebControls.Label lbl1 = new System.Web.UI.WebControls.Label();

lbl1.Text = (empList[item.ItemIndex].phone);
item.Controls.Add(lbl1);

System.Web.UI.WebControls.Label lbl2 = new System.Web.UI.WebControls.Label();

lbl2.Text = (empList[item.ItemIndex].mailid);
item.Controls.Add(lbl2);

}

StringWriter stringWriter = new StringWriter();

HtmlTextWriter writer = new HtmlTextWriter(stringWriter);
testRepeater.RenderControl(writer);

tst.Controls.Add(testRepeater);

Literal lit = new Literal();
lit.Text = stringWriter.ToString();

tst.Controls.Add(lit);
}

}