无法使AJAX代码正常工作

Just getting started with AJAX and tried a simple example in the microsoft 70515 book. However, the code doesnt seem to work, and I can't figure out why not - as it seems ok.

  • Edit: for some reason a part of the code did not get posted, (even as I am writing this now the code looks weird, it is like I can't post all my code??) I've fixad that now- but what's up with the down vote? I cant really see what is stupid about my question. Please explain.

Hoping somebody can spot the problem and help me out here :)

Markup .aspx:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="AjasxTest._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">

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


<br /><br />

<script type="text/javascript">
    function ClientCallbackFunction(args) {
        window.LabelMessage.innerText = args;
    }
</script>

</asp:Content>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="FooterContent">
<asp:DropDownList ID="DropDownListChoice" runat="server" OnChange="MyServerCall(DropDownListChoice.value)">
<asp:ListItem>Choice 1</asp:ListItem>
<asp:ListItem>Choice 2</asp:ListItem>
<asp:ListItem>Choice 3</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="LabelMessage" runat="server"></asp:Label>
</asp:Content>

Code-behind:

namespace AjasxTest
{
    public partial class _Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string callbackRef = Page.ClientScript.GetCallbackEventReference(this, "args", "ClientCallbackFunction", "");

            string callbackScript = String.Format("function MyServerCall(args) {{{0};}}", callbackRef);

            Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"MyServerCall", callbackScript, true);
        }

        public string GetCallbackResult()
        {
            return _callbackArgs;
        }

        string _callbackArgs;

        public void RaiseCallbackEvent(string eventArgument)
        {
            _callbackArgs = eventArgument;
        }
    }
}

Your JS function is called ClientCallbackFunction but you're calling it in the DropDownList OnChange event as MyServerCall.

<script type="text/javascript">
    function ClientCallbackFunction(args) {
        window.LabelMessage.innerText = args;
    }
</script>

...

<!-- Call correct JS function in OnChange -->
<asp:DropDownList ID="DropDownListChoice" runat="server" OnChange="ClientCallbackFunction(DropDownListChoice.value)"> 

...

Your code is pretty close, however the problem is in the fact you are trying to access ServerSide objects (such as Label and DropDownList) from the client side.

For example, an asp:Label control, when rendered to a web browser on the client side, is actually an HTML div. The ID of the label in Visual Studio might be "LabelMessage", but depending on the layout of your page and controls, the ID on the client side (i.e., for the user that clicks view source in FireFox or IE) could be generated as "FooterContent_LabelMessage1" or something like that.

ASP.net controls do come with a property you can use to access the generated ID in JavaScript, which can be accessed by YourControl.ClientID.

I've made these changes to your code and have been able to make it work. I also added some null reference checking in the JavaScript to ensure the objects we are trying to reference, in fact, exist. Note I've tested this in a blank, brand new ASP.net forms application.

Here's the updated code for the Default page (front end):

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="TheAnswer._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <br />
    <br />
    <script type="text/javascript">
        function ClientCallbackFunction(args) {
            var labelMessage = $get("<%= LabelMessage.ClientID %>");
            if (labelMessage) {
                labelMessage.innerText = args;
            }
        }
        function MyServerCallWrapper() {
            var dropDown = $get("<%= DropDownListChoice.ClientID %>");
            if (dropDown) {
                MyServerCall(dropDown.value);
            }
        }
    </script>
</asp:Content>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="FooterContent">
    <asp:DropDownList ID="DropDownListChoice" runat="server" onchange="javascript:MyServerCallWrapper();">
        <asp:ListItem>Choice 1</asp:ListItem>
        <asp:ListItem>Choice 2</asp:ListItem>
        <asp:ListItem>Choice 3</asp:ListItem>
    </asp:DropDownList>
    <asp:Label ID="LabelMessage" runat="server"></asp:Label>
</asp:Content>

Note the $get() function is a built-in ASP.net (not JQuery) function that is shorthand for document.getElementById() - they are interchangeable and do exactly the same thing. You need to pass the ClientID in quotes to either of these methods in JavaScript, and it will return a reference to the object you are trying to access.

Just for fun, I modified one of the back-end functions so you know that the call back was processed on the server:

public string GetCallbackResult()
{
    return _callbackArgs + " from the server!";
}

And voila! this works for me -

Screenshot of Ajax callback result

I hope it works for you too and I hope it's clear where the problem was; most of your example was working / setup perfectly.