ASP.NET 2.0 und CallbackEvents mit Javascript

Ein wenig enttäuscht bin ich schon, vielleicht liegt es aber auch nur an der aktuellen Beta 1 des Microsoft .NET Frameworks. Die CallbackEvents für Javascript, also das Holen von neuen Daten ohne PostBack ist noch viel zu umständlich, und dazu auch noch nicht mächtig genug. Nachfolgend ein kurzes Beispiel für alle, die das neue Feature noch nicht ausprobiert haben:

public partial class Default_aspx : ICallbackEventHandler
{
    public string callBack = "";

    public string RaiseCallbackEvent(string eventArgument)
    {
        if (eventArgument.StartsWith("1"))
            return "eins";
        else
            return "";
    }

    protected override void OnLoad(EventArgs e)
    {
        this.Load += new EventHandler(Default_aspx_Load);
        base.OnLoad(e);
    }

    void Default_aspx_Load(object sender, EventArgs e)
    {
        TextBox1.Attributes.Add("onKeyUp", "GetNumber()");
        callBack = Page.GetCallbackEventReference(this, "Command", "CallBackHandler", "context", "onError");
    }

 

Nachfolgend die .ASPX Datei, die dann eine Funktion aufruft, die man mit Page.GetCallbackEventReference erhält (public string callback):

 

<%@ Page Language="C#" CompileWith="Default.aspx.cs" ClassName="Default_aspx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

<script>

function GetNumber()
{
  var Command = document.forms[0].elements["TextBox1"].value;
  var context = new Object();
  context.CommandName = "GetNumberFunc";
  <%=callBack%>
}

function CallBackHandler(result, context)
{
  if(context.CommandName == "GetNumberFunc")
  {
   
document.forms[0].elements["TextBox1"].value = result;
  }
}

function onError(message, context)
{
  alert(message);
}
</script>

</body>
</html>

Insgesamt finde ich es schade, dass auf der Server Seite dann nicht mehrere einzelne Methoden die Client Aufrufe entgegennehmen. Der CommandName wird nur verwendet, um nach dem erfolgreichen Empfangen der Daten (string) eine Zuordnung zu besitzen. Schlecht ist auch noch, dass immer nur eine Abfrage zur gleichen Zeit gestartet werden kann (soweit ich das verstanden habe).

Wer Lust hat kann sich den Javascript Code, der dann die XmlHttpRequest Objekte verwendet wird, anschauen. Microsoft versteckt den wohl ein wenig, denn mit einem direkten Aufrufen der Javascript URL klappt es nicht (Überprüfung des REFERERs). Aber ein Link in der .ASPX ermöglicht es, den Source Code anzuschauen:

function WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit) {
    this.eventTarget = eventTarget;
    this.eventArgument = eventArgument;
    this.validation = validation;
    this.validationGroup = validationGroup;
    this.actionUrl = actionUrl;
    this.trackFocus = trackFocus;
    this.clientSubmit = clientSubmit;
}
function WebForm_DoPostBackWithOptions(options) {
    var validationResult = true;
    if (options.validation) {
        if (typeof(Page_ClientValidate) == 'function') {
            validationResult = Page_ClientValidate(options.validationGroup);
        }
    }
    if (validationResult) {
        if (options.actionUrl != null && options.actionUrl.length > 0) {
            theForm.action = options.actionUrl;
        }
        if (options.trackFocus) {
            lastFocus = theForm.elements["__LASTFOCUS"];
            if (lastFocus != null) {
                if (typeof(document.activeElement) == "undefined") {
                    lastFocus.value = options.eventTarget;
                }
                else {
                    active = document.activeElement;
                    if (active != null) {
                        if ((typeof(active.id) != "undefined") && (active.id != null) && (active.id.length > 0)) {
                            lastFocus.value = active.id;
                        }
                        else if (typeof(active.name) != "undefined") {
                            lastFocus.value = active.name;
                        }
                    }
                }
            }
        }
    }
    if (options.clientSubmit) {
        __doPostBack(options.eventTarget, options.eventArgument);
    }
}
var __callbackObject = new Object();
function WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback) {
    re = new RegExp("
\\x2B", "g");
    if (__nonMSDOMBrowser) {
        var xmlRequest = new XMLHttpRequest();
        postData = __theFormPostData +
                   "__CALLBACKID=" + eventTarget +
                   "&__CALLBACKPARAM=" + escape(eventArgument).replace(re, "%2B");
        if (pageUrl.indexOf("?") != -1) {
            xmlRequest.open("GET", pageUrl + "&" + postData, false);
        }
        else {
            xmlRequest.open("GET", pageUrl + "?" + postData, false);
        }
        xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xmlRequest.send(null);
        response = xmlRequest.responseText;
        if (response.charAt(0) == "s") {
            if (eventCallback != null) {
                eventCallback(response.substring(1), context);
            }
        }
        else {
            if (errorCallback != null) {
                errorCallback(response.substring(1), context);
            }
        }
    }
    else {
        var xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
        xmlRequest.onreadystatechange = WebForm_CallbackComplete;
        __callbackObject.xmlRequest = xmlRequest;
        __callbackObject.eventCallback = eventCallback;
        __callbackObject.context = context;
        __callbackObject.errorCallback = errorCallback;
        postData = __theFormPostData +
                   "__CALLBACKID=" + eventTarget +
                   "&__CALLBACKPARAM=" + escape(eventArgument).replace(re, "%2B");
        usePost = false;
        if (pageUrl.length + postData.length + 1 > 2067) {
            usePost = true;
        }
        if (usePost) {
            xmlRequest.open("POST", pageUrl, true);
            xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlRequest.send(postData);
        }
        else {
            if (pageUrl.indexOf("?") != -1) {
                xmlRequest.open("GET", pageUrl + "&" + postData, true);
            }
            else {
                xmlRequest.open("GET", pageUrl + "?" + postData, true);
            }
            xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlRequest.send();
        }
    }
}
function WebForm_CallbackComplete() {
    if (__callbackObject.xmlRequest.readyState == 4) {
        response = __callbackObject.xmlRequest.responseText;
        if (response.charAt(0) == "s") {
            if (__callbackObject.eventCallback != null) {
                __callbackObject.eventCallback(response.substring(1), __callbackObject.context);
            }
        }
        else {
            if (__callbackObject.errorCallback != null) {
                __callbackObject.errorCallback(response.substring(1), __callbackObject.context);
            }
        }
    }
}
var __nonMSDOMBrowser = (window.navigator.appName.toLowerCase().indexOf('explorer') == -1);
var __theFormPostData = "";
function WebForm_InitCallback() {
    count = theForm.elements.length;
    var element;
    re = new RegExp("
\\x2B", "g");
    for (i = 0; i < count; i++) {
        element = theForm.elements[i];
         if (element.tagName.toLowerCase() == "input") {
            __theFormPostData += element.name + "=" + element.value.replace(re, "%2B") + "&";
         }
         else if (element.tagName.toLowerCase() == "select") {
            selectCount = element.children.length;
            for (j = 0; j < selectCount; j++) {
                selectChild = element.children[j];
                if ((selectChild.tagName.toLowerCase() == "option") && (selectChild.selected == true)) {
                    __theFormPostData += element.name + "=" + selectChild.value.replace(re, "%2B") + "&";
                }
            }
         }
    }
}
var __disabledControlArray = new Array();
function WebForm_ReEnableControls() {
    if (typeof(__enabledControlArray) == 'undefined') {
        return;
    }
    var disabledIndex = 0;
    for (i = 0; i < __enabledControlArray.length; i++) {
        var c;
        if (__nonMSDOMBrowser) {
            c = document.getElementById(__enabledControlArray[i]);
        }
        else {
            c = document.all[__enabledControlArray[i]];
        }
        if ((c != null) && (c.disabled == true)) {
            c.disabled = false;
            __disabledControlArray[disabledIndex++] = c;
        }
    }
    setTimeout("WebForm_ReDisableControls()", 0);
    return true;
}
function WebForm_ReDisableControls() {
    for (i = 0; i < __disabledControlArray.length; i++) {
        __disabledControlArray[i].disabled = true;
    }
}
var __defaultFired = false;
function WebForm_FireDefaultButton(event, defaultButton) {
    if (!__defaultFired && event.keyCode == 13) {
        if (__nonMSDOMBrowser) {
            src = event.target;
        }
        else {
            src = event.srcElement;
        }
        tagName = src.tagName.toLowerCase();
        if ((tagName != "a") && ((tagName != "input") || ((src.type != "submit") && (src.type != "reset") && (src.type != "image") && (src.type != "file")))) {
            if (defaultButton.click != "undefined") {
                __defaultFired = true;
                defaultButton.click();
                if (__nonMSDOMBrowser) {
                    event.cancelBubble = true;
                }
                return false;
            }
        }
    }
    return true;
}
function WebForm_SaveScrollPositionSubmit() {
    if (__nonMSDOMBrowser) {
        theForm.elements['__SCROLLPOSITIONY'].value = window.pageYOffset;
        theForm.elements['__SCROLLPOSITIONX'].value = window.pageXOffset;
    }
    else {
        theForm.__SCROLLPOSITIONY.value = document.body.scrollTop;
        theForm.__SCROLLPOSITIONX.value = document.body.scrollLeft;
    }
    if (WebForm_ScrollPositionSubmit != null) {
        return WebForm_ScrollPositionSubmit();
    }
    return true;
}
function WebForm_SaveScrollPositionOnSubmit() {
    if (__nonMSDOMBrowser) {
        theForm.elements['__SCROLLPOSITIONY'].value = window.pageYOffset;
        theForm.elements['__SCROLLPOSITIONX'].value = window.pageXOffset;
    }
    else {
        theForm.__SCROLLPOSITIONY.value = document.body.scrollTop;
        theForm.__SCROLLPOSITIONX.value = document.body.scrollLeft;
    }
    if (WebForm_ScrollPositionOnSubmit != null) {
        return WebForm_ScrollPositionOnSubmit();
    }
    return true;
}
function WebForm_RestoreScrollPosition() {
    if (__nonMSDOMBrowser) {
        window.pageYOffset = theForm.elements['__SCROLLPOSITIONY'].value;
        window.pageXOffset = theForm.elements['__SCROLLPOSITIONX'].value;
    }
    else {
        document.body.scrollTop = theForm.__SCROLLPOSITIONY.value;
        document.body.scrollLeft = theForm.__SCROLLPOSITIONX.value;
    }
    if (WebForm_ScrollPositionLoad != null) {
       return WebForm_ScrollPositionLoad();
    }
    return true;
}
function WebForm_TextBoxKeyHandler() {
    if (event.keyCode == 13) {
        if (event.srcElement != null) {
            if (typeof(event.srcElement.onchange) != "undefined") {
                event.srcElement.onchange();
                return false;
            }
        }
    }
    return true;
}

Hoffen wir, dass mit der Beta 2 sich noch einiges ändert!!!

2 Comments

  • Hannes Preishuber said

    da &#228;ndert sich schon ein wenig
    zb der name der Funktion in Client Script Callbacks
    insgesammt ist das schon ne toole sache das Controls wie Gridview und Treeview automatisch davon gebrauch machen.
    Die Verwendung ist nicht einfach aber auch nicht kompliziert
    Ich bin sehr zufrieden damit
    Im &#252;brigen w&#252;rde ich empfehlen Controls nicht per namen anzusprechen da der ganz schnell mal im browser anders sein kann
    document.forms[0].elements[&quot;TextBox1&quot;].value = result;

    Lieber per ControlID

Comments have been disabled for this content.