ASP.NET Webforms Blazor Clone

Aktuell arbeite ich an einem Chat für die ppedv Website. Im Rahmen des Software Entwurfes habe ich mir überlegt die Ideen von Server Side Blazor in Webforms nachzubauen. Dabei wird der HTML Code am Server gerendert und per Websockets zum Browser gesendet.

SignalR Setup

Zuerst wird in das Visual Studio Web Projekt SignalR 2.4 per Nuget installiert. In der Startup.vb (oder cs) muss das Routing für den Hub aktiviert werden.

   1:  Public Partial Class Startup
   2:      Public Sub Configuration(app As IAppBuilder)
   3:          app.MapSignalR()

UserControl ala Partial renderer

In ASP.NET Core kann man per partial, Teile einer HTML Page rendern. Ganz ohne den HTML, Body etc Gedöns außen rum. Dieses HTML Schnipsel wird später zum Client geschickt. Der KLösungsansatz ist ein sogenanntes Benutzersteuerelement oder auch Usercontrol, mit der Endung .ascx

Was das tut ist eigentlich egal. Nur der Vollständigkeit halber mein Chat Part ASPX Part im Usercontrol

   1:  <%@ Control Language="VB" AutoEventWireup="false"
   2:      CodeFile="ChatUserControl.ascx.vb" Inherits="uc_ChatUserControl" %>
   3:  <asp:Repeater ID="Repeater1" ItemType="ChatMsg" runat="server"
   4:      SelectMethod="Repeater1_GetData"
   5:      EnableViewState="false">
   6:      <ItemTemplate>
   7:          <div class="chatcontainer">
   8:              <img src="/images/chat<%#Item.Extern %>.svg" alt="Avatar" 
   9:                  style="width: 100%;" class='<%#If(Item.Extern, "right", "left") %>'>
  10:              <p><%#Item.Nachricht %></p>
  11:              <p><%#Item.User %></p>
  12:              <span class='time-<%#If(Item.Extern, "right", "left") %>'>
  13:                  <%#Item.Zeit.ToShortTimeString%></span>
  14:          </div>
  15:      </ItemTemplate>
  16:  </asp:Repeater>

 

Übrigens ganz modern mit Modelbinding gelöst.

Der SignalR Hub Code

Eine Klasse erbt von Hub und dient als Schnittstelle für eingehende und ausgehende Nachrichten an beliebige Clients. Wir nutzen hier nur den Browser. Es gibt aber auch Signalr implementierungen für WPF und co. Dies nicht unbedingt Thema des ASP.NET Blog Artikels.

   1:  Public Class chathub
   2:      Inherits Hub
   3:      Public Shared ListeMsgs As New List(Of ChatMsg)
   4:   
   5:      Public Async Function NeueNachricht(name As String, msg As String) As Task
   6:    ....
   7:      Await Clients.All.ChatMessage("name", xml)

 

Der HTML Control Renderer

Da sich die Hub Klasse außerhalb der HTTP Request Pipeline befindet, gibt es einiges nicht was man so gewohnt ist. Unter anderem ein Page Objekt, das wir uns ganz frech neu erfinden.

   1:  Public Class EmptyPage
   2:      Inherits Page
   3:      Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
   4:          Return
   5:      End Sub
   6:  End Class

Dies um den kompletten HTML Overhead einfach wegzulassen. Kein HEAD, BODY und co.

In der Hub Klasse wird eine Instanz dieser leeren Page erzeugt, das Usercontrol geladen und gerendert. Im VB.NET Beispiel mit einer statischen Hilfsklasse

   1:  Public Shared Function RenderChat() As String
   2:          Dim p As New EmptyPage ' Page ohne <Form
   3:          Dim ctrl =
   4:              (p.LoadControl("~/UC/ChatUserControl.ascx"))
   5:          ctrl.DataBind()
   6:          Dim sw As System.IO.StringWriter = 
New System.IO.StringWriter()
   7:          Dim hw As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(sw)
   8:          ctrl.RenderControl(hw)
   9:   
  10:          'Update UI
  11:          Return sw.ToString()
  12:      End Function

Diese Zeichenkette wird dann per ChatMessage Signalr an die konnektierten Browser geschickt und einem JavaScript Event übergeben. Also das was im Listing mit ,xml) vorher codiert wurde.

JavaScript im Browser


Diese HTML Zeichenkette kann per Jquery DOM operation einfach einem DIV Chatliste als HTML zugewiesen werden.

   1:   $(function () {
   2:   var chat = $.connection.chathub;
   3:   chat.client.ChatMessage = function (name, msg) {
   4:      $('#chatliste').html(msg);
   5:      };
   6:   
   7:   $.connection.hub.start().done(function () {
   8:    $('#sendmsg').click(function () {
   9:  ...
  10:    });
  11:    });
  12:   });

Mein ASP.NET Webforms Blazor Clone. Verwende ich übrigens produktiv.

Kommentare sind geschlossen