C# – Jquery .ajax async postback on C# UserControl

asp.netcjqueryjson

I'm working on adding a todo list to a project system and would like to have the todo creation trigger a async postback to update the database. I'd really like to host this in a usercontrol so I can drop the todo list onto a project page, task page or stand alone todo list page.

Here's what I have.

User Control "TodoList.ascx" which lives in the Controls directory.

The script that sits at the top of the UserControl. You can see where I started building jsonText to postback but when that didn't work I just tried posting back an empty data variable and removed the 'string[] items' variable from the AddTodo2 method.

<script type="text/javascript">
$(document).ready(function() {
    // Add the page method call as an onclick handler for the div.
$("#divAddButton").click(function() {
        var jsonText = JSON.stringify({ tdlId: 1, description: "test test test" });
            //data: jsonText,
        $.ajax({
            type: "POST",
            url: "TodoList.aspx/AddTodo2",
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(msg) {
                alert('retrieved');
                $("#divAddButton").text(msg.d);
            },
            error: function() {
                alert("error");
            }
        });
    });
});</script>

The rest of the code on the ascx.

<div class="divTodoList">
<asp:PlaceHolder ID="phTodoListCreate" runat="server">
    <div class="divTLDetail">
        <div>Description</div>
        <div><asp:TextBox ID="txtDescription" runat="server"></asp:TextBox></div>
        <div>Active</div>
        <div><asp:CheckBox ID="cbActive" runat="server" /></div>
        <div>Access Level</div>
        <div><asp:DropDownList ID="ddlAccessLevel" runat="server"></asp:DropDownList></div>
    </div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="phTodoListDisplayHeader" runat="server">
    <div id="divTLHeader">
        <asp:HyperLink ID="hlHeader" runat="server"></asp:HyperLink>
    </div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="phTodoListItems" runat="server">
    <div class="divTLItems>
        <asp:Literal ID="litItems" runat="server"></asp:Literal>
    </div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="phAddTodo" runat="server">
    <div class="divTLAddItem">
        <div id="divAddButton">Add Todo</div>
        <div id="divAddText"><asp:TextBox ID="txtNewTodo" runat="server"></asp:TextBox></div>
    </div>
</asp:PlaceHolder>
<asp:Label ID="lbTodoListId" runat="server" style="display:none;"></asp:Label></div>

To test the idea I created a /TodoList.aspx page that lives in the root directory.

<uc1:TodoList runat="server" ID="tdl1" TodoListId="1" ></uc1:TodoList>

The cs for the todolist.aspx

 protected void Page_Load(object sender, EventArgs e)
{
    SecurityManager sm = new SecurityManager();
    sm.MemberLevelAccessCheck(MemberLevelKey.AreaAdmin);
}
public static string AddTodo2()
{
    return "yea!";
} 

My hope is that I can have a control that can be used to display multiple todo lists and create a brand new todo list as well.

When I click on the #divAddButton I can watch it build the postback in firebug but once it completes it runs the error portion by alerting 'error'. I can't see why.

I'd really rather have the response method live inside the user control as well. Since I'll be dropping it on several pages to keep from having to go put a method on each individual page.

Any help would be appreciated.


I wasn't able to get the jquery ajax to work so I backed up and tried just putting the div and the jquery on the page itself and created a webservice.asmx page to handle the postbacks.
I'm still getting the error returned from the jquery and wondering if I've got something configured wrong or some other issue.

Here's the todo.aspx

 <asp:Content runat="server" ContentPlaceHolderID="cpHolder" ID="ContentId">
<div id="divAddButton">Add Todo</div>
<script type="text/javascript">
$(document).ready(function() {
    // Add the page method call as an onclick handler for the div.
    $("#divAddButton").click(function() {
        var jsonText = JSON.stringify({ Todo: { TodoId: 1, Description: "test test test"} });
        //var jsonTextEmpty = jsonText.stringify({""});
        $.ajax({
            type: "POST",
            url: "WebService.asmx/HelloWorld",
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(msg) {
                alert('retrieved');
                $("#divAddButton").text(msg);
            },
            error: function() {
                alert("error");
            }
        });
    });
});

The webservice.asmx is unchanged from the default bit Visual Studio created. Is there a way to find out what is causing the error?

Best Answer

In order to do this with jQuery as you describe, you need to sent it to a decorated method in your ASPX.cs file, you cannot send directly to the .ascx method. The good news is that the aspx.cs method can call the ascx one, so it is really pretty easy and you can just use it as a pass through to that.

[WebMethod]
public static string AddTodo2(myTodo todo2add)
{
 //call your ascx method here
 mymethod(todo2add.td1Id,todo2add.description);
 return "yea!"; 
}

at the end of the aspx.cs, or in another class library put in your class so it knows how to decode the stuff:

public class myTodo
   {
       /// <summary>
       /// web service/webmethod needs 0 parameter constructor
       /// </summary>
       public myTodo()
       {
       }
       public myTodo(int tdlId, string description)
       {
           TdlId= tdlId;
           Description= description;
       }

       public int TdlId;
       public string Description;

   }

slight change to the ajax call:

$("#divAddButton").click(function() {                
   var jsonText = JSON.stringify({myTodo:{ tdlId: 1, description: "test test test" }});
   $.ajax({               
       type: "POST",                
       url: "TodoList.aspx/AddTodo2",                
       data: jsonText,                
       contentType: "application/json; charset=utf-8",                
       dataType: "json",                
       success: function(msg) {                
          alert('retrieved');                
       $("#divAddButton").text(msg.d);                
       },                
       error: function() {                
             alert("error");                
             }                
   });                
});