HowTo: Dynamisch ASP.NET Controls mit AJAX erzeugen

Die Idee (und einige Codezeilen) für dieses HowTo kommt von diesem Blogeintrag der ein tolles Beispiel zeigt. Da ich mir meistens Sachen besser merken kann, wenn ich diese selber mal prototypisch umsetze, schreibe ich auf dieser Basis das HowTo.

Worum geht es?
Stellen wir uns vor, wir hätten viele UserControls geschrieben, welche Daten und Controls unterschiedlicher Art anzeigen können.
Wenn man nun allerdings eine schöne “Web 2.0″ AJAX Anwendung bauen will, schickt man im einfachsten Fall JSON Daten hin und her und muss sich das Control über Javascript zusammenbauen. Das ganze ist natürlich nicht sehr wartbar (manches wird über ASP.NET gemacht, manches vielleicht über statisch eingebundene Controls und andere Sachen über Javascript) – schön wäre doch, wenn man die Controls dynamisch auf die Seite holen könnte. Und genau darum geht es heute…

Aufbau:

image

Wir haben ein sehr simples “SampleUserControl”:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SampleUserControl.ascx.cs" Inherits="DynamicASPControls.SampleUserControl" %>
<div style="background-color: red; height: 200px; top: 200px">
    Fertig geladen \o/
</div>

Der ScriptService:

Für die Kommunikation zwischen Client und Server (und die AJAX Funktionalität) nutzen wir ASP.NET AJAX. Wie das geht und was man damit machen kann, habe ich hier bereits beschrieben.

Im ScriptService (der auch das Attribut ScriptService trägt) erstellen wir uns dynamisch den HTML Code von einem beliebigen Usercontrol:

public class ScriptService : System.Web.Services.WebService
    {
        [WebMethod(EnableSession = true)]
        public string GetControlHtml(string controlLocation)
        {
            Page page = new Page();
            UserControl userControl = (UserControl)page.LoadControl(controlLocation);
            userControl.EnableViewState = false;
            HtmlForm form = new HtmlForm();
            form.Controls.Add(userControl);
            page.Controls.Add(form);
            StringWriter textWriter = new StringWriter();
            HttpContext.Current.Server.Execute(page, textWriter, false);
            return CleanHtml(textWriter.ToString());
        }

        /// <summary>
        /// Removes Form tags
        /// </summary>
        private string CleanHtml(string html)
        {
            return Regex.Replace(html, @"<[/]?(form)[^>]*?>", "", RegexOptions.IgnoreCase);
        }
    }

Der “GetControlHtml” Methode wird die “Location” von dem Control mitgeiteilt und jetzt bauen wir uns dynamisch eine “Page” zusammen und fügen eine “HtmlForm” dazu und hängen dort das geladene Control dran.

Über “HttpContext.Current.Server.Execute” können wir nun unseren fertigen HTML Code in ein String verwandeln.

Die “CleanHtml” Methode entfernt die Form Tags am Anfang wieder – sodass wir möglichst nur noch das original Control-HTML übrig haben.

Größenbeschränkung aufheben:

Da man ja relativ viele Sachen in einem Control machen kann und das daraus resultierende HTML recht groß werden kann, müssen wir dies in der Web.Config erst freischalten:

  <system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization maxJsonLength="5000000" />
      </webServices>
    </scripting>
  </system.web.extensions>

Fertige ASPX:

Die fertige ASPX Seite ist bewusst einfach gehalten:

<%@ Page Language="C#" AutoEventWireup="true" EnableViewState="false" CodeBehind="Default.aspx.cs" Inherits="DynamicASPControls._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

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

</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Services>
            <asp:ServiceReference Path="~/ScriptService.asmx" />
        </Services>
    </asp:ScriptManager>

    <button type="button" onclick="generateUserControl()">Generate UserControl!</button>
    <div id="result">

    </div>
    </form>

        <script type="text/javascript">
        function generateUserControl()
        {
            document.getElementById("result").innerHTML = "Load...";
            DynamicASPControls.ScriptService.GetControlHtml("~/SampleUserControl.ascx", generateUserControlCompleted);
        }

        function ready(result)
        {
            alert(result);
        }

        function generateUserControlCompleted(result)
        {
            document.getElementById("result").innerHTML = result;
        }

        function failed(error)
        {
            alert(error);
        }

    </script>
</body>
</html>

Über die JavaScript Methoden greifen wir auf den Service zu, welcher uns das HTML liefert. In der “generateUserControlCompleted” Methode schreiben wir das HTML nur noch in unser “result” div:

image
(Design made by me ;) )

Ein komplexeres Beispiel:

Ein wesentlich komplexeres Beispiel findet ihr in diesem Blogpost, sowie eine jQuery Variante in diesem Blogpost.

Wo es Probleme geben könnte:

Da wir das HTML dynamisch zur Seite hinzufügen, funktioniert sicherlich das Postback System von ASP.NET nicht (bzw. könnte ich es mir vorstellen, dass es da Probleme gibt) – für ein einfaches Control, welches ohne PostBacks entwickelt wurde, ist es aber sicherlich eine tolle Sache.

[ Download Sourcecode ]

HowTo: Microsoft AJAX Client API nutzen

Bereits einmal in einer Wöchentlichen Rundablage erwähnt, möchte ich mich heute mal der AJAX Client API widmen. Die Client API wird oft kaum genutzt, obwohl manche kleinen Helferlein praktisch sind. Infos zu den ASP.NET AJAX Extensions (also der serverseitigen API gibt es z.B. hier in einem HowTo).

Was ist die ASP.NET AJAX Client API?

Die AJAX Client API ist entweder für ASP.NET Entwickler direkt in dem Download der ASP.NET AJAX Extensions (oder ASP.NET 3.5) enthalten oder auch als seperater Download zu bekommen. Die Client API kann auch in PHP, JSP, Ruby usw. eingesetzt werden, da es nur eine Javascript Bibliothek ist.

Ich werde mit den ASP.NET AJAX Extensions arbeiten, allerdings sind die clientseitigen Sachen später auch bei PHP und co. gültig.

Wie wird diese eingebunden?

Sobald man in ASP.NET den Scriptmanager mit einfügt, ist die Client API sofort mit eingebunden und wird mitgeladen:

image

(in PHP und co. muss die Installationsanleitung bei dem seperaten Download angesehen werden)

Ein Blick in die DOM verrät uns, was alles mit geladen wurde (und das ist nur ein Ausschnitt):

image

Was hat man nun davon?

Die Microsoft AJAX API bietet einige kleine Helferlein, welche einem das Javascript-Leben erleichtern können – das dabei aber natürlich immer ein gewisser “Respekt” dabei sein sollte, sollte für alle klar sein: Nur weil eine Bibliothek “verrückte” Sachen erlaubt, heisst das noch lange nicht, dass man diese nutzen muss.

Die kleinen Helferlein zeige ich mal kurz an 5 Beispielen:

1. Zugriff auf ein DOM Element

Der Zugriff erfolgt immer über “document.getElementById(…)” oder ähnlichem – die Microsoft AJAX API stellt dafür ein kleine Abkürzung bereit – den “$get Shortcut“. Das erleichtert immerhin die Tipparbeit ;)

2. Eventhandler dynamisch anhängen

Ein Element dynamisch per Javascript mit einem Event versehen ist etwas haarig, da der ID nicht alles mit macht und mir spontan allein 3 Wege einfallen wie man das “klassisch” lösen kann:

  • über innerHTML die Events “reinschreiben” (das versteht wenigstens auch der IE)
  • über setAttribute (geht beim IE manchmal nicht)
  • über die jeweiligen Eventeigenschaften direkt (wenn man den Syntax nicht direkt im Kopf hat, ist es etwas nervig)

Die Microsoft AJAX API erlaubt über den “$addHandler Shortcut” genau das. Leider kann man wohl leider keinen Parameter oder weiteren Kontext mitgeben.

Für dieses Thema empfehle ich diesen Blogbeitrag, da er auch einige andere Features zeigt, z.B. kann man über den “event” Parameter rausbekommen, welcher Knopf gedrückt wurde (Enter z.B.) oder wo die Mausposition etc. ist (Wie sowas mit normalen JS geht, wird hier erklärt.)

3. Strings verknüpfen

Einen String mit JS über das “+” zu erzeugen, wird dann schwierig, sobald Zahlen dirn vorkommen. Zahlen werden dann sofort addiert und erst danach an die nachfolgende Zeichenfolge drangeklebt. Das ist nicht immer den Effekt, den man sich wünscht.

Microsoft stellt hier eine “StringBuilder” Klasse zur Verfügung.

4. Umgang mit Arrays

In Zeiten von JSON etc. arbeitet man wieder viel auf der Clientseite und möchte angenommen jedes Element eines Arrays an eine spezielle Methode übergeben, damit dieser weiter verarbeitet werden kann. Im normalen JS muss man nun hier erst eine Schleife durchlaufen lassen etc.

Microsoft stellt hier eine “Array.forEach” Methode bereit, die genau dies macht. Die Methode gehört zu den Array Type Extensions, welcher noch andere Extensions angehören.
Dazu ist wahrscheinlich auch dieser Blogeintrag sehr interessant und empfehlenswert.

5. Datumsanzeige

Wie gerade erwähnt, hat Microsoft einige “Extensions” für normale JS “Typen” bereitgestellt, darunter auch einer für den “Date” Typ. Dieser hilft, Datumsformatierungen wesentlich einfacher vor zu nehmen, als in der klassischen Variante. Die “Microsoft” Variante ist aus den bekannten Java oder .NET entnommen und daher eigentlich nichts unbekanntes. Siehe dazu am besten den unteren Abschnitt von diesem Blogeintrag.

Mein Demoprojekt und den Source Code:

Die 5 Beispiele können live auch hier angesehen werden und habe ich im IE7 und Firefox 2 getestet. Da dies alles nur Javascript Code ist, findet ihr auch dort den Source Code.

Fazit:

Die Client API ist sehr interessant wenn man sich einmal eingearbeitet hat und stellt einige Erleichterungen bereit. Einen Blick ist sie auf alle Fälle wert und wenn man ohnehin die ASP.NET AJAX Server Funktionalitäten nutzt, kann man die vom Client doch auch mal mit einbauen.

Die komplette Client Reference findet ihr hier.

[ Demoanwendung + Sourcecode ]

Microsoft Press verschenkt LINQ, ASP.NET AJAX und Silverlight 1.0 e-Books

Zur Weihnachtszeit gibts was sehr interessantes von Microsoft Press: 3 EBooks gratis (Voraussetzung ist nur eine Windows Live ID)

Downloaden könnt ihr das ganze auf der Microsoft Learning Website (dort ist ein Link “Download Free e-book offer…” – da drauf klicken und Windows Live ID und noch wenige andere Angaben machen) – Topaktuelle Bücher kostenlos ist doch immer schön.

Gefunden habe ich dies auf einem Schweizer MSDN Blog.

In dem Zusammenhang möchte ich nochmal die laufende Aktion von Entwickler-Press erwähnen – bis zum 24. ist es zwar nicht mehr lang, aber ein paar Bücher kann man sich noch runterladen.

Erster Eindruck von ASP.NET MVC mit dem Visual Web Developer Express

Die ASP.NET Extension CTP ist schon eine kleine Weile verfügbar, jedoch bin ich erst heute dazu gekommen, mir dies mal anzuschauen.

Da ich auf meinem privat Notebook kein Visual Studio 2008 Standard (oder höher) hab, benutze ich den Visual Web Developer 2008 (was wahrscheinlich bei vielen Leuten zutrifft).

Vorbereitung: 

ASP.NET 3.5 Extensions installieren und Visual Web Developer Web Site “MVC tauglich” machen

Nachdem man die CTP installiert hat, findet man im Visual Web Developer zwar eine Vorlage für “ASP.NET 3.5 Extensions Web Site”, allerdings unterstützt die CTP momentan nur Web Projects – daher nützt uns das nur sehr wenig.

Eine Installationsanleitung befindet sich hier. Insbesondere muss man da auch die Kommentare lesen, dann wird es klarer. Aber nochmal zusammengefasst:

  • web.config unter dem Punkt “system.web”-”pages” anpassen:
         <namespaces>
            <add namespace="System.Web.Mvc"/>
            <add namespace="System.Linq"/>
         </namespaces>

(warum weiß ich auch noch nicht so genau, das bekommen wir bestimmt noch raus ;) )

  • global.asax und Default Routing unter “Application_Start()” hinzufügen:
    void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.Add(new Route
        {
            Url = "[controller]/[action]/[id]",
            Defaults = new { action = "Index", id = (string)null },
            RouteHandler = typeof(MvcRouteHandler)
        }); 

    }
  • Ordnersturktur anpassen:

image

Erklärung: Unter “App_Code” befinden sich unsere Controller und Models, die Views kommen ins Root Verzeichnis.

Die Default.aspx im Rootverzeichnis ist komplett leer.

Der Ordner “Shared” ist für Masterpages, User Controls etc. gedacht.

Mein .ASPX Seiten haben kein Codefile mehr, sondern erben direkt von “System.Web.Mvc.ViewPage”, z.B.:

<%@ Page Language="C#"     MasterPageFile="~/Views/Shared/Site.master"     AutoEventWireup="true"     Inherits="System.Web.Mvc.ViewPage"    Title="Bookstorage | Search" %>

Die Masterseite ist normal, enthält aber kein “form” Tag und auch keinen ScriptManager für ASP.NET AJAX – da müsste man nochmal genau nachschauen wie  man das geschickt macht (darauf komme ich später nochmal).

Die Webapplikation strukturieren

Insgesamt ist die Website sehr simpel gehalten, daher bitte nicht wundern.

Das Model

Es gibt eine einfache “Book” Klasse sowie eine Klasse “BookCollection”, welche von “List<Book>” erbt.
Der “BookCollectionManager” hat eine Methode “GetBookCollection”, welche einfach so eine Collection zurückgibt.

Die Controller

Der HomeController macht nix großes bzw. sieht man das auch gut am SearchController wie ich diesen aufgebaut habe:

public class SearchController : Controller
{

    [ControllerAction]
    public void Index()
    {
        RenderView("Index");
    }

    [ControllerAction]
   public void Results(string query)
   {
        BookCollectionManager man = new BookCollectionManager();
        BookCollection data = man.GetBookCollection(query, 1);
        ViewData["BookCollection"] = data;
        RenderView("Results");
   }
}

In dem Controller geibts einmal den Index (der laut unserer Routingtabelle in der globals.asax der Default Controller ist) und sagt nur, dass er den View “Index(.aspx)” Rendern soll. Dabei sucht er genau in dieser Ordnerstruktur nach “Search” etc.

Unsere “Results” Methode ist eigentlich unsere Suchmethode und spricht unser Backend (was einfach nur eine Collection an 25 Einträgen zurück gibt) an. Die Daten werden dann in ViewData gespeichert und autoamtisch übergeben. Scott hat auch noch andere Methoden beschrieben – dies war erstmal die Einfachste. Dannach wird der View “Results” gerendert.

Daten an den Controller übergeben

Zwar haben wir jetzt unseren Controller, aber wie übergeben wir diesem was?

Ganz einfach über ein HTML Formular:

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolderContent" Runat="Server">
<form id="searchform" action="/Intro/Search/Results" method="post">
    <span>Search:</span>
    <input type="text" name="query" />
    <button type="submit">Suchen</button>
</form>

</asp:Content>

Die Form verweisst auf unsere “Results” Methode – wichtig dabei ist, dass der name des übergebenen Parameter mit dem der Methode übereinstimmt. Dies stößt unseren Controller an, welcher dann wiederrum den View rendert.

Problem mit ASP.NET AJAX:
Hier will ich nochmal kurz mein Problem mit dem ScriptManager erläutern. Da ich in der Masterpage kein “form” hab (wie im normalen ASP.NET) üblich, sondern es nur dort einsetzen möchte, wo ich es für sinnvoll halte (wie z.B. hier) und die action URL je nachdem darauf ausrichten möchte, gibt es leider ein Problem mit ASP.NET AJAX.
Dadurch kann man den ScriptManager nur unschön in die MasterPage hinzufügen, da dieser ein “<form runat=”server”>… verlangt. Eine Lösung gibt es bestimmt (vielleicht über das MVCToolkit) oder man fügt den ScriptManager auf den Seiten hinzu, wo man ihn benötigt. 2 Formuale (eine in der Masterpage & eine auf der Contentpage) ist irgendwie “unschön”, aber da müsste man nochmal nachschauen. Microsoft macht sich selbst auch Gedanken und ich denke, da kommt noch eine bessere Integration insgesamt, weil man zwar den ScriptManager einsetzen könnte, aber dann wiederrum die Controller etc. übergeht – und das ist ja nicht Sinn der Sache.

Die übergebenen Daten darstellen

In jedem View benutze ich meine simple Masterpage, daher ist dies der wesentliche Code in der “Result.aspx”:

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolderContent" Runat="Server">
Search Results:

<table>
<%foreach (var returnBook in (BookCollection)ViewData["BookCollection"])  { %>
<tr>
    <td><%= returnBook.Title %></td>
    <td><%= returnBook.Description %></td>
    <td><%= returnBook.PicUrl %></td>
</tr>
<% } %>
</table>
</asp:Content>

Über “ViewData["BookCollection"]” greife ich auf meine Daten zu und gebe sie einfach so aus. Ob nun “var” (also ein anonymer Typ) da richtig ist, weiß ich noch nicht ganz ;) , es funktioniert jedenfalls:

image

Das Demoprojekt testen/download & Fazit

Startet nicht das Projekt wenn ihr gerade die ASPX Seiten geöffnet habt, da dann z.B. bei der Result.aspx eine Exception geworfen wird ;) – öffnet die leere Default.aspx und gebt dann manuell die jeweiligen URLs (siehe oben) ein.

Wenn man sich erstmal eingearbeitet hat, macht es sehr viel Freude, zu sehen, dass man diesmal volle Kontrolle über den HTML Code hat und es (jedenfalls für mich) klarer ist, wie man bestimmte HTML Elemente dynamisch rendert. Das es noch hier und da (ASP.NET AJAX) Schwierigkeiten gibt, ist natürlich bei so einer Preview verständlich.
Dies waren auch nur meine ersten Schritte, sodass ich wahrscheinlich noch nicht alles optimal gemacht habe ;)

[ Download Source Code ]

HowTo: Erstellen eines Silverlight 1.0 Videoplayers mal auf einfache Weise

Silverlight ist Microsofts Antwort auf Flash und wurde direkt für den Einsatz als Videoplayer entwickelt, doch wie genau funktioniert das? Wie bindet man ein Video ein und ist das kompliziert?

Die Antwort: Nein, es ist sehr leicht einen simplen Videoplayer zu erstellen – genau das will ich heute zeigen.

Alternativen zu meiner Lösung:

Mein Beispiel soll nur die Grundlagen zeigen und auf simple Art und Weise das zeigen, was z.B. mit dem Expression Encoder oder Popfly möglich ist.

Schritt 1: MS AJAX Enabled Website erstellen und Silverlight.js hinzufügen

Wir erstellen einfach (aus Gewohnheit) ein ASP.NET AJAX enabled Website und fügen die Silverlight.js aus dem SDK hinzu (und fügen diese Javascript Datei noch der Default.aspx hinzu) :

image

Schritt 2: Videoplayer XAML erstellen

Als nächstes erstellen wir das XAML für den Videoplayer. In unserem Fall werden wir uns auf das wesentliche beschränken und werden über normale HTML Buttons das Video steuern.

Hier erstmal das XAML:

<Canvas
   xmlns="http://schemas.microsoft.com/client/2007"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Width="399" Height="360"
   OpacityMask="#FF000000"
   RenderTransformOrigin="0.5,0.5"
   >
   <MediaElement
   x:Name="Player"
   Source="http://www.code-inside.de/files/democode/silverlightvideoplayer/Lake.wmv"
   AutoPlay="True"
   Stretch="Fill"/>
</Canvas>

In unserm Canvas Element, welches das Root Element ist, fügen wir das MediaElement ein, welches unser Video einbindet.

Wichtig beim MediaElement: Damit wir es über Javascript ansprechen müssen, müssen wir einen “x:Name” vergeben – in unserem Fall “Player” und noch eine “Source” setzen.
Interessanter Hinweis noch dazu:

Das Video wird bei mir auf code-inside.de gehostet – die Anwendung selbst läuft auf code-developer.de:

image

Schritt 3: SilverlightHost einfügen und ein paar Buttons

Sobald unsere Seite aufgebaut ist, wird das Silverlight in dem “SilverlightVideoHost-Div” erstellt und darüber sind 3 schnöde Buttons mit den jeweiligen Javascript Funktionen:

  • Play
  • Stop
  • Pause
<body onload="createSilverlight()">
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <div>
            <button onclick="play()">Play</button>
            <button onclick="stop()">Stop</button>
            <button onclick="pause()">Pause</button>
        </div>
        <div id="SilverlightVideoHost">
        </div>
    </form>
</body>

Schritt 4: SilverlightHost erstellen und Funktionalität implementieren

Als finalen Schritt rufen wir jetzt die Silverlight.js auf und erstellen unseren Videoplayer:

    function createSilverlight()
    {
    Silverlight.createObjectEx({
      source: "Videoplayer.xaml",
      parentElement: document.getElementById("SilverlightVideoHost"),
      id: "SilverlightControl",
      properties: {
         width: "100%",
         height: "100%",
         version: "1.0"
      },
      events: {
         onError: null,
         onLoad: null
      }

   });
   }

Wichtig hier ist die “source” – unser “Videoplayer.xaml” – sowie das übergeben unseres “SilverlightVideoHost” als “parentElement” und vergeben noch eine “id” “SilverlightControl“.

Jetzt statten wir noch die 3 Buttons mit einer Funktion aus:

   function play()
   {
   var control = document.getElementById("SilverlightControl");
   control.Content.FindName("Player").play();
   }

   function stop()
   {
   var control = document.getElementById("SilverlightControl");
   control.Content.FindName("Player").stop();
   }

   function pause()
   {
   var control = document.getElementById("SilverlightControl");
   control.Content.FindName("Player").pause();
   }

Wir greifen hier direkt über Javascript auf das Silverlight zu. Um auf das Silverlight Plugin zuzugreifen bekommt man es über document.getElementById(SILVERLIGHT_ID) – nicht zu verwechseln mit der SilverlightHostID:

  • SilverlightControl = Ist ID des generierten “objects” und erlaubt es auf die Silverlight DOM zuzugreifen (siehe hier für weitere Infos)
  • SilverlightVideoHost = Ist ID des Hosts des Silverlight Plugins

Über das Silverlight Plugin haben wir nun die Möglichkeit die jeweiligen Methoden des MediaElements aufzurufen:

Als Ergebniss haben wir dann unseren simplen Videoplayer:

image

 

[ Demoanwendung | Source Code Downloaden ]

Neues kleines HowTo – PageMethods mit ASP.NET AJAX

In einem neuen kleinen HowTo zeige ich, wie man sehr einfach PageMethods erstellt und das man den ganzen AJAX Style auch ohne (manchmal) lästige ASMX Datei hat:

[Hier zum Artikel]

HowTo: Microsoft ASP.NET AJAX (PageMethods – Webmethoden aufrufen ohne ASMX Datein)

In diesem HowTo erklärte ich, wie man eine ASMX Datei so erweitern kann, dass man die Methoden auch über Javascript (und über den ScriptManager) zugänglich macht.
Da man allerdings nicht immer eine ASMX Datei erstellen will um vielleicht nur eine kleine Aufgabe zu erledigen gibt es die so genannten PageMethods.

Da das nicht weiter schwer ist, werde ich kurz die Schritte zeigen:

Schritt 1: AJAX Enabeld Website erstellen & ScriptManager anpassen

Durch das Template (wie man das bekommt, ist hier beschrieben)

<asp:ScriptManager ID=”ScriptManager1″ runat=”server” EnablePageMethods=”True” />

Wichtig hier ist das “EnablePageMethods” auf “True” zu setzen.

Schritt 2: Die PageMethod in der Code Behind erstellen

Meine einfache PageMethod sieht so aus:

[WebMethod]
public static string HelloWorld(string name)
{
    return “Hello World ” + name;
}

Die wichtigen Teile sind fett markiert. Für das “WebMethod” Attribut muss der Namespace “System.Web.Services” eingebunden werden. Erst durch dieses Attribut baut der ScriptManager den JS Wrapper drum herum.
Der nächste (und sehr wichtige Punkt) – nur statische Methoden können genutzt werden. Um die Objekthierarchie von ASP.NET nicht zu zerstören, können keine Instanzmethoden aufgerufen werden. In der CTP ging dies wohl noch, wurde aber aus Sicherheitsgründen aus dem Release herausgenommen. Allerdings hat man Zugriff auf die Session oder kann dort andere Klassen aufrufen.

Schritt 3: Die Methode im Javascript ansprechen

Die entscheidente Javascriptzeile (die Demoapplikation kann unten runtergeladen werden):

PageMethods.HelloWorld(”Robert”, onComplete);

Über das Javascript Objekt “PageMethods” sind alle Methoden zu finden, welche mit dem WebMethod-Attribut ausgestattet sind und statisch sind. Dann einfach die jeweilige Methode aufrufen und freuen.

image

[Download Demo Source Code]

Microsoft AJAX + Amazon + Windows Live Bildersuche Style = ShoppingMap

Ich hab mich mal hingesetzt und das was ich in den ganzen HowTos alles berichtet habe, mal praktisch umzusetzen. Hier sind alle Informationen samt Source Code:

ShoppingMap

Neues HowTo zu Silverlight 1.0

Eigentlich hätte es bereits in dem vergangenen HowTo vorkommen müssen, aber in dem neuen HowTo zeige ich, wie man den Spiegeleffekt dynamisch gestalten kann und wie man per Javascript auf Silverlight zugreift. Am Ende nutzen wir noch die Features von den ASP.NET AJAX Extensions um die “volle Kraft” zu nutzen die Microsoft hier bietet.

Hier zum Artikel

Neues HowTo zum Thema ASP.NET AJAX

Nach den 2 HowTos wo es um die Basics um AJAX ging sowie die 2 HowTos wo es um die Basics von dem Microsoft ASP.NET AJAX Framework ging, kommt heute eine Sache zur Sprache, die wohl das tollste Feature darstellt: Der Clientseitige Aufruf von Webmethoden.

Sogar mit Bildern – dank dem Windows Live Writer.

 

Grüße,

Robert

HowTo: Microsoft ASP.NET AJAX (Clientseitiger Aufruf von Webmethoden)

Diese mal geht es um das eigentlich tollste Feature von Microsofts ASP.NET AJAX Framework. Wie wiederholt erwähnt ist das UpdatePanel nicht wirklich ideal, da es erstmal alle Daten zum Server hinschickt und hinterher die Antwort zwar etwas weniger ist, aber trotzdem bei weitem nicht optimal ist.

Daher gibt es so genannte “Scriptmethoden” – es ist eigentlich das, was viele Anfänger in der Webprogrammierung machen wollen: Aus Javascript eine C#/.NET Methode aufrufen.

Wie man das ASP.NET AJAX Framework installiert, ist hier beschrieben.

Schritt 1: ASP.NET AJAX enabled Web Site erstellen

image 

Durch das Template bekommt man am Ende den App_Data Ordner sowie die Default.aspx und die bereits angepasste Web.Config. In der Web.Config sind allerhand Assemblys etc. registriert. Wer interessiert ist, kann sich diese gerne anschauen, allerdings sind da keine weiteren Änderungen notwendig.

Der wichtigeste Teil steht jetztin der Default.aspx: Der Scriptmanager. Dieser ScriptManager übernimmt später die “hässliche” Drecksarbeit – aber dazu erst später.

Schritt 2: Ein Webservice erstellen und “pimpen”

image

Jetzt erstellen wir einen neuen Webservice – der z.B. Datenbanken abfragen kann oder andere Berechnungen durchführen könnte. Bei unserem Beispiel gibt der Webservice nur ein kleinen dummen Text zurück.

Unserer Webservice – die HelloWorld.asmx – verweisst auf die Codebehinde-Datei HelloWorld.cs und dort drin steht unser eigentlicher Code.
Momentan ists es noch genau so, wie bei einem normalen XML Webdienst, nun kommt allerdings das i-Tüpfelchen drauf: Das ScriptService Attribut.
Dieses versteckt sich im System.Web.Script.Services Namespace und muss daher vorher eingebunden werden.

using System;using System.Web;        

using System.Collections;        

using System.Web.Services;        

using System.Web.Services.Protocols;        

using System.Web.Script.Services;/// <summary>        

/// Zusammenfassungsbeschreibung für HelloWorld        

/// </summary>        

[ScriptService]        

[WebService(Namespace = "http://tempuri.org/")]        

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]        

public class HelloWorld : System.Web.Services.WebService {        

public HelloWorld () {        

//Auskommentierung der folgenden Zeile bei Verwendung von Designkomponenten aufheben         

        //InitializeComponent();         

    }        

[WebMethod]        

    public string HelloWorldTest(string name) {        

        return "Hello World" + name;        

    }        

}        

Ganz oben ist der ScriptService eingebunden – ansonsten bleibt alles gleich.

Schritt 3: Dem ScriptManager sagen, dass es den Service gibt

Damit unser ScriptManager auf der Default.aspx auch weiß, dass es den Service gibt und beim Aufruf einen Javascript-Wrapper drum rum setzt, muss er erst bekannt gemacht werden. Der ScriptManager kann auch auf einer Masterpage eingesetzt werden – allerdings ist pro Seite nur einer erlaubt. Mehr wäre auch unsinnig. Hier der benötigte Code:

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

                <asp:ServiceReference Path="HelloWorld.asmx" />        

            </Services>        

        </asp:ScriptManager>        

 

Schritt 4: Das Javascript bauen und die Methode ausprobieren

Jetzt werden wir mal testen, ob das auch wirklich so funktioniert:

    <script language="javascript" type="text/javascript">
    function ladefunktion() 
     {        

    HelloWorld.HelloWorldTest("Reman", onComplete);        

    }        

function onComplete(result)        

    {        

    alert(result);        

    }        

</script>

Die “ladefunktion()” schreiben wir einfach in das body Element als onload oder sonstwo hin und schon sehen wir, ob das klappt: Bei mir klappts. Der Javascript Aufruf der Webmethode ist entweder [Klasse].[MethodenName]([Parameter], [Javascript-Callbacks]) oder [Namespace].[Klasse].[MethodenName]([Parameter], [Javascript-Callbacks]).

Schritt 5: Verstehen was passiert

Der ScriptManager macht wie gesagt die Drecksarbeit davon, er bastelt im Hintergrund einen Javascript Wrapper um die Webmethode. Man kann das auch mit einer Methode machen, welche man im Codebehinde hat, allerdings ist das heute nicht das Thema.
Der Spannende Teil ist der Aufruf der Methode: Er ist identisch mit dem Aufruf als würde ich ihn im Codebehinde ansprechen – mit einem Unterschied – ich übergebe hier 2 Parameter. Einmal meinen direkten Parameter und einmal eine Callback Javascript Methode. Man kann bis zu 3 Callback Methoden angeben. Wenn man nur ein Parameter zusätzlich angibt, ist das die Methode wenn die Anfrage komplett abgearbeitet wurde. Die 2 anderen Parameter die möglich sind, sind für Fehlerfälle gedacht. Leider kann ich momentan nicht sagen, in welcher Reihenfolge die man angeben muss.

Das was als “result” bei der onComplete zurück kommt ist ein JSON – jedenfalls wenn man nichts anderes sagt. Man kann bei dem Service noch ein weiteres Attribute angeben: Das ResponseFormate – wo man zwischen JSON und XML wählen kann:

    [WebMethod] 
    [ScriptMethod(ResponseFormat.Xml)]        

    public string HelloWorldTest(string name) {        

        return "Hello World" + name;        

    }
 

Man kann noch ein paar mehr Parameter angeben, aber so genau wollen wirs ja nicht machen. JSON ist ein sehr schickes, schmales Format, was auch sehr leicht verständlich ist. Auf die Objekte in dem JSON greift man dann so zu ”Objekt.Objekt.Objekt…” - ähnlich wie im Codebehinde.

Schritt 6: AJAX Ladebalken einbauen

Einen tollen Ladebalken kann man auch leicht implementieren – ohne irgendwelche komplexen Dinge aus dem Toolkit. Einfach bei der “ladeFunktion” das AJAX-Loader Gif auf “display: block” setzen und bei onComplete wieder auf “display: none”.

Jetzt hat man ne coole Web 2.0 Seite mit dem ASP.NET AJAX Framework gemacht ;)

Fazit:

Also mit diesen tollen Feature kann man sehr schnell seine ganzen Webservices sehr leicht per Javascript erreichen. Natürlich geht das auch ohne das AJAX Framework, aber dadurch geht es doch sehr schnell. Man kann somit jetzt eine ASP.NET Seite bauen, welche im Prinzip nur aus Javascript und Webservices besteht – schöne neue Welt ;)

Neuer Artikel: Microsoft ASP.NET AJAX (Praktischer Anfang)

Ich hab mich mal wieder hingesetzt um einen relativ kurzen Artikel über den Einstieg in das Microsoft AJAX Thema geschrieben.

[Hier zum Artikel]

Da es manchmal verwirrend ist, wie man denn nun das Toolkit installiert und wie man am besten die Toolkit Controls in die Toolbox bekommt, hab ich mir gedacht, dass der Artikel ganz hilfreich sein kann. Die wirklich interesanten Themen werde ich allerdings wohl erst später anschneiden.

Schönen Tag noch.

HowTo: Microsoft ASP.NET AJAX (Praktischer Anfang)

Nun da die Grundlagen bereits beschrieben sind, möchten ich den praktischen Teil angehen.

Unser Ziel ist es eine einfache ASPX Seitee zu bauen, welche mit tollen AJAX Effekten glänzt. Dazu wollen wir auch das Control Toolkit nehmen.

Schritt 1: Grundlagen beachten

Wie in dem anderen HowTo bereits gesagt, gibt es 2 Teile die Microsoft bereitstellt. Die ASP.NET AJAX Extensions müssen installiert sein.
Sobald man diese installiert hat, bekommt man ein neues Template zur Auswahl: ASP.NET AJAX-Enabled Web Site/Application

Bemerkung am Rande:
Der Unterschied zwischen einer Webapplication und einer Website wird hier gut dargestellt.

Schritt 2: Website erstellen

Ich entscheide mich aus Einfachheitsgründen für eine Web Site und wähle das Template für “AJAX Enabled Web Sites”.
Dadurch habe ich nun in meiner Toolbox 5 neue Controls (Erklärungen folgen später) :
- Timer
- ScriptManager
- ScriptManagerProxy
- UpdatePanel
- UpdateProgress

Schritt 3: Toolkit reinladen

Zwar denk ich, dass ich irgendwo schonmal ein Template dafür gesehen habe, aber ich lad mir das Toolkit seperat in meine Web Site rein. Dazu lad ich mir das Toolkit runter und entpacke es.
Nun geh ich wieder zu meiner Website und füge ihr die Toolkit dll hinzu (Rechtsklick auf die Website > Verweis hinzufügen… > Durchsuchen). Die Toolkit dll versteckt sich in der SampleWebsite. Dort im “Bin” Ordner befindet sich die “AJAXControlToolkit.dll“.
Nachdem ihr diese dll eurem Projekt hinzugefügt habt, wird in eurem Bin Ordner jetzt viele Ordner erstellt werden – für die unterschiedlichen Sprachen etc.

Schritt 4: Die Controls in der Toolbox sichtbar machen

Damit man später die tollen Controls direkt per Drag&Drop auf seine Website ziehen kann, müssen wir diese noch in die Toolbox (dort wo alle Controls drin liegen) bekommen.
Dazu ein Rechtsklick auf ein freies Feld und klickt “Registerkarte hinzufügen” und nun ein Name eingeben (AJAX Toolkit z.B.).
Als nächstes dann wieder ein Rechtsklick drauf und dann “Elemente auswählen” > “Durchsuchen” und euer Bin Verzeichnis Suchen (bei mir liegts da: C:\Users\Robert\Documents\Visual Studio 2005\WebSites\TestWebsite\Bin) und die Toolkit dll hinzufügen. Dannach nochmal bestätigen und schon hat man alle Controls in der Toolbox.

Schritt 5: Loslegen

Jetzt kann man wie man will seine ASPX Seite zusammenbauen und die Vorzüge von AJAX genießen. Ich möchte jetzt einfach mal auf die How-Do-I Videos verweisen, wo schon sehr viel erklärt wird. Ansonsten ausprobieren.

In einem nächsten Artikel werd ich dann zu den richtig interessanten Themen kommen – zum Beispiel clientseitige Aufrufe von Webdiensten oder die Einbindung des teilweise zickigen Toolkits.

[Zum nächsten HowTo: Microsoft ASP.NET AJAX (Clientseitiger Aufruf von Webmethoden)]

Gute und schlechte Seiten des UpdatePanels…

Da ich noch recht neu in dem Gebiet von Microsoft AJAX Implementierung bin, durchstöber ich immer wieder nach neuen Informationen dazu das Netz.

Einen sehr interessanten und deutschsprachigen Artikel zum UpdatePanel gibts auf den Microsoft MSDN Seiten zu finden.

[Hier gehts zum Artikel]

Neues HowTo: ASP.NET AJAX

Obwohl ich momentan noch in der Entwicklung von “ShoppingMap 2.0″ bin, habe ich nochmal kurz einen Artikel zu Microsofts ASP.NET AJAX Framework- (Früher bekannt als Atlas) geschrieben.

Viel Spaß.