In a previous post "Partial page rendering", we have looked into ASP.NET Ajax basics - partial rendering using UpdatePanel control. In this article you will see another way to perform partial page rendering and that is - by calling a ScriptService from JavaScript.
Let's see why UpdatePanels are not always a good solution. UpdatePanels are very simple and it is very easy to turn your classic aspx pages into ajax-enabled pages. However, this has its own downsides:
- Each request includes full ViewState that travels to the server and back to the client
- Full web page lifecycle still remains
- The size of the response is still large since the whole portion of HTML markup is rendered
When developing complex applications, this could be a point for potential blunders. Much more optimization can be achieved by putting ScriptServices into the game.
What are ScriptServices?
ScriptService is actually a special type of WebServices that allows script calls. Beside the [WebService] attribute it has one more required attribute [ScriptService]. This tells us that this service can be accessed by JavaScript. Each method can have an optional [ScriptMethod] attribute.
ScriptServices are mostly local services, defined within the application (asmx file). They use JSON streams for data exchange. JSON (JavaScript Object Notation) is a lightweight data-interchange format. This is why partial rendering using ScriptServices can be much more efficient - you have speed, no ViewState and true asynchronous calls.
Now when we know what ScriptServices are, let's see how to call script methods and how to parse a response.
I am going to use the same database and data access object (DAO) as in the previous example, but I will simplify user interface. The goal of this example will be to show a number of Internet users for a country selected in drop down list.
DAO contains methods that retrieve a list of countries and number of Internet users for a specific country. We'll wrap these methods in CountryWS ScriptService. Below is the source code of CountryWS:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class CountryWS : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod]
public Country GetCountry(int countryID)
{
CountryDAO dao = new CountryDAO();
return dao.GetCountry(countryID);
}
[WebMethod]
[ScriptMethod]
public string GetCountryInternetUSers(string countryName)
{
CountryDAO dao = new CountryDAO();
return dao.GetCountryInternetUSers(countryName).ToString("N0");
}
}
As you can see, one method returns the Country object, and the other just a string representation of a number. This is another advantage - you have the full object model that you can work with on the client. To make this clearer, please take a look at the code on the aspx page:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/CountryWS.asmx" />
</Services>
</asp:ScriptManager>
<div>
<div style="border: solid 1px #dcdcdc; padding: 10px;">
Country:
<asp:DropDownList ID="ddlCountries" runat="server">
</asp:DropDownList>
<input id="bthShowCountries" type="button" value="Show"
onclick="OnShowCountriesClick()" />
</div>
</div>
<asp:Panel ID="pnlDetails" runat="server" Style="display: none;">
<hr />
Internet users:
<div id="divInternetUsers" style="display: inline;">
</div>
</asp:Panel>
For ScriptService to be visible, you have to register it in the <services> section of a ScriptManager. Next, btnShowCountries button will call OnShowCountriesClick() method to perform a call to CountryWS. Let's take a look at JavaScript code on the same page:
<script type="text/javascript">
function OnShowCountriesClick()
{
var country = $get('ddlCountries').value;
CountryWS.GetCountryInternetUSers(country, OnRequestComplete)
}
function OnRequestComplete(result)
{
var details = $get('pnlDetails');
details.style.display = "block";
var users = $get('divInternetUsers');
divInternetUsers.innerHTML = result;
}
</script>
OnShowCountriesClick() method will get the selected country and pass it as a parameter when calling CountryWS.GetCountryInternetUsers. Function OnRequestComplete() will handle the response that is passed as a "result" parameter. Result will be a string you can see in CountryWS.
To have a complete picture of what is happening during the request, here is a screenshot of WebDevelopmentHelper
As you can see, the request is a JSON string that contains just the name of the country - Brazil in this case. The response is also a JSON string containing the number of Internet users for Brazil. Quick, easy, no ViewState and no full page lifecycle.
Summary
In this article you saw how to perform a partial page rendering using a Web (or Script) service. However, this is not the only way to call a ScriptService. For more information, please check the following excellent articles:
Please don't forget to download sample code.
