ASP.NET AJAX and Unknown Web Method
When you work with open source projects, you get spoiled: sometimes there's good documentation, usually there's a good community, and you always get access to the code. Rarely is life so good when using the proprietary Microsoft stack.
The DynamicPopulateExtender AJAX control (demonstration) is a control which lets you populate a region of the page with a string (probably HTML) in response to another element being clicked. I'm trying to use it to create a control similar to the autocomplete text boxes that one tends to come across these days, only I'd like it to be rendered as a drop-down list - I don't want to post back arbitrary text.
The ListSearch is almost there; but I don't want to always download a 100,000-row dataset to my page to render. I would like the search to take place as I type, and for the server to populate the dropdown on the client with results in real time. I'm hoping that the DynamicPopulateExtender will allow me to squirt a list out to the client dynamically.
The aspx page will look something like this:
<asp:ScriptManager
runat="server"
ID="_scriptManager"
/>
<ajaxToolkit:DynamicPopulateExtender
TargetControlID="_updateTarget"
runat="server"
ID="_searchExtender"
PopulateTriggerControlID="_searchBox"
ServiceMethod="Foo"
ServicePath="TestTA.aspx"
/>
<asp:TextBox
ID="_searchBox"
runat="server"
/>
<asp:Panel ID="_updateTarget" runat="server">
<em>Enter search phrase...</em>
</asp:Panel>
Pretty simple. The idea here is that when you click on the _searchBox TextBox, the browser invokes the 'Foo' method on the TestTA.aspx page. This method returns a string which is plugged right into the _updateTarget panel.
According to the docs (and all the other blogs that are out there) your code behind should contain something like this:
using System.Web.Services;
using System.Web.Script.Services;
namespace Test
{
public partial class TestTA : System.Web.UI.Page
{
[WebMethod]
[ScriptMethod]
public string Foo(string contextKey)
{
return "Hello world!";
}
}
}
Again - no surprises there. Note that you need to decorate your method with both [WebMethod] and [ScriptMethod].
Except - it doesn't quite work. When you click the element on the page, you'll find an HTTP 500 error returned. Digging into your logs, you'll find something like this:
Exception information:
Exception type: ArgumentException
Exception message: Unknown web method Foo.
Parameter name: methodName
The key missing piece is that the Foo method must be marked as static. This wasn't mentioned explicitly in any how-tos that I found (although the code on an MSDN blog post includes it).
Your final code-behind will therefore look something like this:
using System.Web.Services;
using System.Web.Script.Services;
namespace Test
{
public partial class TestTA : System.Web.UI.Page
{
[WebMethod]
[ScriptMethod]
public static string Foo(string contextKey)
{
return "Hello world!";
}
}
}
I hope that stops someone else tearing their hair out.
I've disabled comments for now due to spam problems - I'll turn them back on when I've fixed it!
Comments
1 Chris Georgakopoulos says...
Tnx Tnx Tnx !!!
Posted at 11:55 a.m. on November 10, 2008
2 Teddy Ruxpin says...
Hi, thanks for your note on using static. I was about to start crying like a baby.
BTW, not sure if [ScriptMethod] is required...I believe adding this does introduce a large surface area for attackers, where if you can get away with just the features of [WebMethod], you should just use that.
Thanks!
Posted at 2:28 p.m. on December 31, 2008