Friday, October 21, 2011

Placing a Web Method in a Page

In most cases, it makes sense to create a separate web service to handle your ASP.NET AJAX callbacks.
This approach generally results in clearer pages and makes it easier to debug and refine your code.
However, in some situations you may decide you have one or more web methods that are designed
explicitly for use on a single page and that really shouldn't be reused in other parts of the application. In
this case, you may choose to create a dedicated web service for each page, or you might choose to move
the web service code into the page.

Placing the web method code in the page is easy—in fact, all you need is a simple bit of cut-andpaste.
First, copy your web method (complete with the WebMethod attribute) into the code-behind class
for your page. Then, change it to a static method, and add the System.Web.Script.Services.ScriptMethod
attribute. Here's an example where the web method (named GetTerritoriesInRegion) is placed in a web
page named WebServiceCallback_PageMethods:

public partial class WebServiceCallback_PageMethods : System.Web.UI.Page
{
   [System.Web.Services.WebMethod()]
   [System.Web.Script.Services.ScriptMethod()]
   public static List<Territory> GetTerritoriesInRegion(int regionID)
   {
      // Farm the work out to the web service class.
      TerritoriesService service = new TerritoriesService();
      return service.GetTerritoriesInRegion(regionID);
   }
...
}

Next, set the ScriptManager.EnablePageMethods property to true, and remove the reference in the
<Services> section of the ScriptManager (assuming you don't want to use any non-page web services):

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

Finally, change your JavaScript code so it calls the method through the PageMethods object, as
shown here:

PageMethods.GetTerritoriesInRegion(regionID, OnRequestComplete, OnError);

The PageMethods object exposes all the web methods you've added to the current web page.
One advantage of placing a web method in a page is that the method is no longer exposed through
an .asmx file. As a result, it's not considered part of a public web service, and it's not as easy for someone
else to discover. This is appealing if you're trying to hide your web services from curious users.
Another reason you might choose to code your web methods in the page class is to read values from
view state or the controls on the page. When you trigger a page method, a stripped-down version of the
page life cycle executes, just like with the ASP.NET client callback feature you saw in Chapter 29. Of
course, there's no point in trying to modify page details because the page isn't being rerendered, so any
changes you make will simply be discarded.