jQuery autocomplete und aufruf eines asmx webservice per get

Beschäftige mich aktuell intensiver mit dem System Umbraco. Dabei versuch ich einen Datentyp für die Administration zu entwicklen, der per AJAX Daten aus einer Datenbank lädt. Ein Datentyp in Umbraco ist z.B. ein Textfeld, Checkbox oder ähnliches um im Adminbereich das System mit Inhalten zu befüllen.Bei meiner Suche bin ich dann auf ein jQuery-Plugin namens autocomplete aufmerksam geworden. Damit kann man eine Textbox via JavaScript mit einer autocomplete-Funktion erweitern. Da ich die Daten aber nicht per JSON direkt mit zum Client übertragen wollte, habe ich dafür einen asmx-Webservice geschrieben. Die Einbindung via jQuery ist denkbar einfach und sieht in C# z.B. so aus: private void _BuildAutoCompletedScript() { StringBuilder clientScript = new StringBuilder(); clientScript.Append(" <script type='text/javascript'>"); clientScript.Append(" $(document).ready(function() { "); clientScript.AppendFormat(" $(\"#{0}\").autocomplete( ",                                           this.autoCompleteTextbox.ClientID); clientScript.Append(" \"/umbraco/webservices/api/mywebserive.asmx/mymethod\", "); clientScript.Append(" { delay:10, minChars:2,                                       matchContains:1, cacheLength:10, autoFill:true } "); clientScript.Append(" ); "); clientScript.Append(" }); "); clientScript.Append(" </script>"); this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.ClientID +                                        "_autocompleteData", clientScript.ToString()); this.Page.ClientScript.RegisterClientScriptInclude("jquery.autocomplete",                                 "/umbraco_client/Application/JQuery/jquery.autocomplete.js");Auf der Serverseite wird dann eine Web-Servicemethode definiert: [WebService(Namespace = "uri:umbraco-irgendwas")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.Web.Script.Services.ScriptService] public class mywebservice : System.Web.Services.WebService { [WebMethod] public string mymethod(string q, int limit) { return "Hello World" + q; } }Die Parameter q und limit wird vom Plugin automatisch beim Aufruf als Parameter übergeben. Dabei ist q der Inhalt aus dem Textfeld und limit ist die maximale Anzahl an Datensätzen, die zurück geliefert werden sollen.So weit so einfach, doch leider habe ich beim Aufruf immer einen http-Fehlercode 500 bekommen. Die Lösung habe ich noch einiger Recherche dann gefunden.Die web.config muss um folgendes ergänzt werden:<webServices>   <protocols>     <add name="HttpGet"/>     <add name="HttpPost"/>     <add name="HttpSoap"/>   </protocols> </webServices>sonst kann der Web-Service nicht via GET aufgerufen werden.

but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control

In unserem DotNetNuke Shop Modul wird im Administationsbereich einiges mit ASP.NET AJAX durchgeführt. Bisher verlief die Installation der Entwicklungsumgebung auch immer ohne Probleme. Bei einem Kollegen, kam es aber zu einer echt blöden Fehlermeldung: DotNetNuke.Services.Exceptions.ModuleLoadException: The base class includes the field 'pnlExtPrice', but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control (System.Web.UI.UpdatePanel). ---> System.Web.HttpParseException: The base class includes the field 'pnlExtPrice', but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control (System.Web.UI.UpdatePanel). ---> System.Web.HttpParseException: The base class includes the field 'pnlExtPrice', but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control (System.Web.UI.UpdatePanel). at System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildFieldDeclaration(ControlBuilder builder) at System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildSourceDataTreeFromBuilder(ControlBuilder builder, Boolean fInTemplate, Boolean topLevelControlInTemplate, PropertyEntry pse) at System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildSourceDataTreeFromBuilder(ControlBuilder builder, Boolean fInTemplate, Boolean topLevelControlInTemplate, PropertyEntry pse) at System.Web.Compilation.TemplateControlCodeDomTreeGenerator. BuildMiscClassMembers() at System.Web.Compilation.BaseCodeDomTreeGenerator.BuildSourceDataTree() at System.Web.Compilation.BaseTemplateBuildProvider.GenerateCode(AssemblyBuilder assemblyBuilder) at System.Web.Compilation.AssemblyBuilder.AddBuildProvider(BuildProvider buildProvider) --- End of inner exception stack trace --- at System.Web.Compilation.AssemblyBuilder.AddBuildProvider(BuildProvider buildProvider) at System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders() at System.Web.Compilation.BuildProvidersCompiler.PerformBuild() at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath) at System.Web.UI.TemplateControl.LoadControl(String virtualPath) at DotNetNuke.UI.Skins.Skin.InjectModule(Control objPane, ModuleInfo objModule, PortalSettings PortalSettings) --- End of inner exception stack trace --- Eigentlich war alles so weit auch richtig installiert und in einer anderen DNN Installation lief AJAX ohne größere Probleme. Auf dem Rechner war neben ASP.NET 2.0 auch bereits .NET 3.5 installiert und ich dachte mir schon, das es irgendein Konflikt mit den Versionen sein muss. Eine Recherche im Web hat mich dann auf folgendes Ergebnis gebraucht: In der web.config muss der Bereich "runtime" wie folgt angepasst werden:<runtime>      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">        <probing privatePath="bin;bin\HttpModules;bin\Providers;bin\Modules;bin\Support;" />        <dependentAssembly>          <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35" />          <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />        </ependentAssembly>        <dependentAssembly>          <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35" />          <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />        </dependentAssembly>      </assemblyBinding>    <runtime>  Danach läuft das Modul und die AJAX Funktionen - hier im speziellen das UpdatePanel - wieder ohne Probleme.    

ASP.NET ajax GenerateScriptType und eigene Komplexe Typen

Ich beschäftige mich gerade mal etwas intensiver mit dem AJAX-Framework - eigentlich ja schon ein alter Hut. Dabei habe ich ein DotNetNuke-Modul, dass zu einem ASMX-WebService Daten versendet und ein Ergebnis zurück bekommt. namespace G.Modules.LicCalc{  [WebService(Namespace = http://tempuri.org/)]    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  [ScriptService]  public class CalculatorService : System.Web.Services.WebService  {    [WebMethod()]    public string HelloWorld(LicCalcInfo info)    {       return "Hello World" + info.LinuxLicense.ToString();    }  }  } Passend dazu gibt es eine Klasse "LicCalcInfo" - die wie DotNetNuke-typische Info-Class aufgebaut ist using System;namespace GMS.Modules.LicCalc.Business{public class LicCalcInfo{private int _windowsLicense;private int _linuxLicense;public int LinuxLicense{get { return _linuxLicense; }set { _linuxLicense = value; }}public int WindowsLicense{get { return _windowsLicense; }set { _windowsLicense = value; }}}} Wenn ich jetzt über JavaScript versuche die Methode "HelloWorld" aufzurufen und den Parameter LicCalcInfo übergeben möchte, wird bei der Erstellung der Klasse immer eine JavaScript-Exception ausgelöst. Das JavaScript sah so aus: function HelloWorld(){var info = new LicCalcInfo(); info.LinuxLicense = 10;DocuSnap.Modules.LicCalc.CalculatorService.HelloWorld(info, SucceededCallback);}function SucceededCallback(result, eventArgs){    alert(result);} Das ganze funktioniert aber nur, wenn die Klasse "LicCalc" direkt in der ASMX Datei definiert wurde und sich außerhalb des Namespaces befindet. Als extern definierte Klasse habe ich die Einbindung nie geschafft. Die Lösung dabei ist aber mal wieder relativ einfach: Bei der Erzeugung des Objektes in JavaScript muss das Objekt mit dem kompletten Namespace angesprochen werden.. das hat mir dann ein Blick in die automatisch gernierte JavaScript-Datei veraten. Der Aufruf zur Erzeugung muss dann so geschrieben werden: var info = new DocuSnap.Modules.LicCalc.Business.LicCalcInfo(); Dann kann die Klasse auch in JavaScript erzeugt werden und die Verarbeitung wird erfolgreich durchgeführt.

ASP.NET Ajax das Updatepanel und der FCKEditor

Heute habe ich versucht, den FCKEditor innerhalb eines ASP.NET Ajax Updatepanel dazu zu bewegen mir auch den eingegebenen Text auszuhändigen. Normalerweise ist ja die Einbindung und Nutzung vom FCKEditor innerhalb von DotNetNuke denkbar einfach. Also wie gewohnt die Arbeitsschritte ausgeführt und mal mutig F5 gedrückt. Leider mit dem Resultat, dass die Eigenschaft Text vom FCKEditor nach einem partial PostBack immer leer war und der Text zunächst mysteriös verschwand. Die Suchmaschine meines Vertrauen hat mir auch prompt ein paar Hinweise zu dem Thema ausgespuckt - gut, ich war wohl nicht alleine auf dieser Welt. Auf der Seite http://jlcoady.net/archive/2007/03/30/fckeditor-work-inside-updatepanel wurde ein Lösungsansatz vorgestellt, der aber leider so nicht ganz funktioniert - zumindest im meinem Fall nicht. private void Page_Load(object sender, EventArgs args){   Page.ClientScript.RegisterOnSubmitStatement(   editor.GetType(),   "editor",   "FCKeditorAPI.GetInstance('" + editor.ClientID + "').UpdateLinkedField();");} Dieser Code-Snippet bracht mich nicht weiter, denn der Text wurde immer noch nicht zurück geliefert, nach einem Postback innerhalb vom UpdatePanel. Auch der folgende Code sollte angeblich funktionieren, konnte aber meine FCKEditor auch nicht wirklich übereden, mal endlich seine Arbeit aufzunehmen. this.Page.ClientScript.RegisterOnSubmitStatement( this.GetType(), "AjaxHack", "for ( var i = 0; i < parent.frames.length; ++i ) if ( parent.frames[i].FCK ) parent.frames[i].FCK.UpdateLinkedField();" ); Wie sich nun herausstellt, sind die Scripte vollkommen in Ordnung und funktionieren auch. Nur ist es empfehlenswert die Methode "RegisterOnSubmitStatement" nicht als Methode der Page aufzurufen sondern als Methode vom ScriptManager. Das sieht dann so aus: ScriptManager sm = ScriptManager.GetCurrent(Page);if (sm != null){ScriptManager.RegisterOnSubmitStatement(this.Page,this.GetType(),"FCKAjaxHack","for ( var i = 0; i < parent.frames.length; ++i ) if ( parent.frames[i].FCK ) parent.frames[i].FCK.UpdateLinkedField();");} Oh Wunder, jetzt funktioniert auch der FCKEditor in der Zusammenstellung von DotNetNuke, ASP.Net Ajax und dem Updatepanel!

.NET AJAX .axd und der Fehler utcDate out of the range

Bei der Neuinstallation eines Windows 2008 Server mit ASP.NET 2.0 und AJAX bekam ich beim Abruf von Resourcen über WebResource.axd und ScriptResource.axd jeweils den Fehler: Specified argument was out of the range of valid values.Parameter name: utcDate Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.Parameter name: utcDateSource Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.   Lösung: Das liegt an der Systemzeit vom Windows Server. Zunächst sollte diese Zeit überprüft werden und falls nötig auf das aktuell Datum / Uhrzeit gesetzt werden. Sollte dadurch der Fehler nicht behoben werden, dann einfach unter Software die Installation von AJAX mit der Option "Reparieren" durchführen. Es scheint hier wohl eine Fehler zu geben und ASP.NET AJAX kommt dann mit dem Datum nicht zurecht. Nach der "erneuten" Installation funktioniert dann alles wie gewollt!  

Setzen von ASP.NET Server Variables in JavaScript

Habe soeben eine ziemlich schön (zumindest auf dem ersten Blick) ASP.NET Komponente entdeckt, die einem die relativ einfach Möglichkeit bietet serverseitige Variablen an den Client Browser zu übergeben. Dafür gibt es hier eine Klasse, die einem die Verwaltungsarbeit abnimmt. Der Weg: var CustomerName = '<%= Customer.Name %>'; ist ja nicht wirklich elegant und ich persönlich finde es immer schlechten Stil, wenn man in einer ASPX-Seite anfängt und Serverseitigen Code schreibt. [Nein, bitte keine Grundsatzdiskussion - einfach meine Meinung :)] Viel optimaler unter ASP.NET ist doch die folgende Möglichkeit:protected void Page_Load(object sender, EventArgs e){   wwScriptVariables scriptVars = new wwScriptVariables();   // *** Add any values static or dynamic   scriptVars.Add("CustomerName", Customer.Name);   // *** Done} Auf dem Client kommt das dann in folgender Form an Automatisch werden dann die definierten Variablen an den Browser als JavaScript übermittelt und sieht so aus: <script type="text/javascript"> //<![CDATA[var serverVars = {    "name": "Müller, Maier, Schmitu"}//]]></script> Ein Zugriff innerhalb von JavaScript gestaltet sich auch denkbar einfach: var name = serverVars.name; Also ich finde diese Lösung verdammt sexy und für den täglichen Alltag auf jeden Fall zu gebrauchen!

Die ASP.NET AJAX Extensions sind fertig / RTW

Die ASP.NET AJAX Extensions haben das Betastadium verlassen und sind nun RTW (Ready-to-Web). Diese Bibliothek integriert sich vollständig in das ASP.NET 2.0 Framework und liefert sowohl serverseitige Funktionalität als auch eine plattformübergreifend clientseitige JavaScript-Bibliothek. Dadurch soll es möglich sein auch bestehende Anwendungen mit minimalem Aufwand AJAX fähig zu machen. Eine erste Anlaufstelle für AJAX ist die Website: http://ajax.asp.net/ Der direkte Downloadlink zur AJAX Extension ist hier.