Ajax Callback aus Razor View

Schon länger schwirrt mir ein Gedanke im Kopf herum. Aus längerer Erfahrung mit Angular.js und REST APis wie die ASP.NET Web Api heraus empfinde ich leichte Schmerzen, wenn das Objektmodell am Server und am Client definiert und erzeugt wird. Warum lasse ich mal außen vor. Eigentlich ist das HTML Rendering am Server und die DOM Manipulation oft eine einfachere Lösung. So wie ASP.NET Webforms das mit  mit dem Updatepanel im Ergebnis löst.  Darum habe ich mir die Möglichkeiten von ASP.NET Core Razor einmal angesehen.

Zum Einsatz kommt

ASP.NET Core 2.2 Webforms
Partial View Usercontrol aus Webforms
Page Handler Methods Event Handler von UI Controls
unobtrusive Ajax JS Library Updatepanel

 

Damit wird eine Liste angezeigt. Diese wird initial mit der Page mitgerendert, so wie man das bei dynamischen Web Seiten macht. Wenn der Benutzer einen Button drückt, wird die Liste aktualisiert. Um das Verhalten Löschen, Einfügen, Editieren mit zu implementieren werden Hyperlinks eingesetzt, die im Parameter dann z.B. die ID des ausgewählten Datensatzes aus einer Liste übergibt. Das wird aber nur konzeptionell mit einem Link gezeigt.

image

 

Die Unobtrusive Ajax Bibliothek

Das Problem des Ajax Callbacks löse ich mit Jquerys $Http Callback. Dann noch ein wenig JavaScript Code um das Callback zu behandeln und das DOM zu manipulieren. Mit erstaunen entdecke ich

Install-Package Microsoft.jQuery.Unobtrusive.Ajax -Version 3.2.6

13 Millionen Downloads geben dem auch einen gewissen seriösen Anstrich und der letzte Build ist 3 Monate alt. Leider ist die Dokumentation etwas spärlich. Außerdem ist mir weder per Nuget noch dem neuen Client Side Library Installer aus Visual Studio 2017 es gelungen, die JS Datei dem Projekt hinzuzufügen. Gelöst per Copy Paste aus der Github Projekt url.

Wenn man sich völlig von JavaScript fernhalten will, kann mit dieser Bibliothek einfach per Attribute im HTML Code Funktion deklariert werden. Data-Ajax bewirkt, das das entsprechende markierte HTML Element Ajax Postbacks auslöst. Wobei die Methode mit Ajax-Method gewählt werden kann, also auch ein GET. Die Ajax Url verweist auf die entsprechend benannte Page Method. Zuletzt werden noch zwei DIV benötigt um die Wartemeldung einzublenden und das letztendlich mit dem Ergebnis des Callbacks das enstprechende HTML DOM Element auszutauschen.

 

   1:   <form method="post" data-ajax="true"
   2:      data-ajax-url="/teilweisepage/Partial"
   3:      data-ajax-loading="#spinner"
   4:      data-ajax-method="post"
   5:      data-ajax-update="#placeholder"
   6:   >

Statt dem ajax-update lässt sich auch per Ajax-Complete eine JacaScript Methode anspringen.

 

Partials

Razor Pages in Teilansicht werden Partials genannt. In der Regel nutzen Entwickler den Unterstrich als Präfix im Namen und platzieren diese Datei in Pages/Shared. Für die Demonstration eines Razor Partials wurden zwei Varianten gewählt. Eine die eine Liste erstellt und das zweite was anderes.

_teilweisePartialEmpty.cshtml

   1:  <table>
   2:      <tr>
   3:          <td>empty</td>
   4:      </tr>
   5:  </table>

_teilweisePartial.cshtml

   1:  @using Microsoft.AspNetCore.Http.Features
   2:   
   3:  <table>
   4:      @for (int i = 0; i < 10; i++)
   5:      {
   6:          <tr>
   7:              <td>
   8:                  @i
   9:          </td>
  10:          <td>@DateTime.Now.Ticks</td>
  11:      </tr>
  12:  }
  13:  </table>

Das using ist obsolet und wurde im Code belassen um zu zeigen, das man auch in Partials analog zur Page C# codieren kann.

HTML Page Methods

Die klassische Razor Page hat im CodeBehind, in ASP.NET Core Page Model Klasse genannt, eine OnGet Methode. Diese wird ausgeführt wenn die Seite vom Browser mit Get aufgerufen wird. Praktisch das Page_load aus Webforms. Um weitere benannte Handler zu aktivieren, nutzt das MVC Pattern das sogenannte Routing. Im Kern stellt der Url Pfad die Funktion dar (Analogie Webforms FriendlyUrls). Ein TeilweisePage/Partial mappt dann zu einer Funktion OnGetPartial. Die Route wird in der Razor Page wie folgt als optional (?) deklariert

@page "{handler?}"

Wenn der Benutzer so wie im HTML Code ganz am Anfang dargestellt den Button drückt, landet er in OnPostPartial (Form Post Action). So weit so gut, aber wirklich cool ist es sich den Partial HTML Code einfach rendern zu lassen und als Rückgabe an den Browser zu schicken.

   1:  public IActionResult OnPostPartial()
   2:   {
   3:      return Partial("_TeilweisePartial"); //2.2??
   4:   }

Soweit ich das gelesen habe ist die Funktion Partial (oder PartialAsync) eine Neuerung von ASP.NET Core 2.2.

Die gleiche Lösung für einen Hyperlink (Leer) der GET nutzt.

   1:  public IActionResult OnGetLeer()
   2:  {
   3:              return Partial("_TeilweisePartialEmpty"); //2.2??
   4:   }

Wer einen Parameter von HTML Formular an den Server Code übergeben möchte kann dies per Page Model Attribut und Binding lösen. Dazu in der Page Klasse Property einfügen und Attribut versehen.

 

   1:  [BindProperty]
   2:  public string Para1 { get; set; }

Im finalen HTML Coder der Razor Page wird dann das DIV als Placeholder angelegt. Aber wir füllen es initial beim Page Load mit Server gerenderten HTML. Im FORM Element kann nur eine Page Method ausgelöst werden. Es macht also keinen Sinn mehrere Buttons darin zu platzieren. Eine Lösung ist mehrere Form Elemente anzulegen mit unterschiedlichen ajax-Url die dann in die passen Handler Methoden münden.

 

   1:  <div id="placeholder"><partial name="_TeilweisePartial" /></div>
   2:   
   3:  <form method="post" data-ajax="true"
   4:            data-ajax-url="/teilweisepage/Partial"
   5:            data-ajax-loading="#spinner"
   6:            data-ajax-method="post"
   7:            data-ajax-update="#placeholder"
   8:    >
   9:    Name: <input type="text" asp-for="Para1" /><br>
  10:    <input type="submit" />
  11:  </form>
  12:  <div id="spinner">lade...</div>
  13:      
  14:  <a asp-page-handler="Leer"
  15:         data-ajax="true"
  16:         data-ajax-url="/teilweisepage/Leer"
  17:         data-ajax-loading="#spinner"
  18:         data-ajax-method="get"
  19:         data-ajax-update="#placeholder">Speakers</a>
  20:      <script src="~/lib/jquery.unobtrusive-ajax/jquery.unobtrusive-ajax.js"></script>

Single Page Applications sind möglich. Ganz ohne JavaScript Code oder schwergewichtigen MVx Librarys wie Angular, Ract oder Vue.

Kommentare sind geschlossen