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 [1]">
<html xmlns="http://www.w3.org/1999/xhtml [2]" > <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 [3]", "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 [3]", "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!!!