Verwandtschaftssuche – Funktionen zur statistisch semantische Suche

Im vorhergehenden Artikel Statistisch semantische Suche haben wir das notwendige Werkzeug für den SQL Server eingebunden: Die Semantik Datenbank und den Microsoft Office Paketfilter.

imageimage

Nun soll die Semantik auch mal für uns tun. Mit Hilfe 3er Funktionen können wir einiges herausfinden:

Funktion 1: SEMANTICKEYPHRASETABLE

SEMANTICKEYPHRASETABLE hilft uns dabei die Schlüsselwörter aus Dokumenten herauszufinden.

Der Funktionsrumpf sieht dabei so aus:

SEMANTICKEYPHRASETABLE ( table, { column | (column_list) | * } [ , source_key ] ) --So zum Beispiel DECLARE @DocID hierarchyid SELECT @DocID = path_locator from Akten where name = 'Workflow.docx'; SELECT SEMANTIKTAB.keyphrase, SEMANTIKTAB.score from SEMANTICKEYPHRASETABLE ( Akten, file_stream, @DocID ) AS SEMANTIKTAB ORDER BY SEMANTIKTAB.score DESC;

Und hier mein Ergebnis dazu:

imageimage

So finden wir schon mal raus, welche Schlüsselwörter ein Dokument enthält und in welcher Gewichtung. So könne wir schon mal rausfinden welche Dokumente ähnlich sind.

Funktion 2: SEMANTICSIMILARITYTABLE

Die Funktion gibt als Ergebnis die Dokumente zurück, die aufgrund der Semantik dem angegeben ähneln, sprich sich in den Schlüsselwörtern inkl Gewichtung ähnlich sind.

SEMANTICSIMILARITYTABLE ( table, { column | (column_list) | * }, source_key ) --Zunächst suchen wir uns die Idee des Dokuments raus.. DECLARE @DocID hierarchyid SELECT @DocID = path_locator from Akten where name = 'Workflow.docx'; SELECT mft.name, sst.score FROM SEMANTICSIMILARITYTABLE ( Akten, file_stream, @DocID ) AS sst INNER JOIN Akten mft ON path_locator = matched_document_key ORDER BY score DESC


Und so sieht mein Ergebnis hier aus..

image

Je höher der Score, umso ähnlicher das Dokument.

Ach ja.. Wenn zwei oder mehr Dokumente den gleichen Score aufweisen, kann man davon ausgehen, dass es sich um Kopien handelt Zwinkerndes Smiley

Funktion 3: SEMANTICSIMILARITYDETAILSTABLE

Warum ist dieses Dokument eigtl ähnlich mit einem anderen. Die Funktion SEMANTICSIMILARITYDETAILSTABLE schlüsselt uns das etwas genauer aus:

SEMANTICSIMILARITYDETAILSTABLE ( table, source_column, source_key, matched_column, matched_key ) DECLARE @DocID hierarchyid DECLARE @DocIDVergleich hierarchyid SELECT @DocID = path_locator from Akten where name = 'Workflow.docx'; SELECT @DocIDVergleich = path_locator FROM Akten WHERE name = 'Security.docx'; SELECT TOP(5) TAB.keyphrase, TAB.score FROM SEMANTICSIMILARITYDETAILSTABLE ( Akten, file_stream, @DocID, file_stream, @DocIDVergleich ) AS TAB ORDER BY TAB.score DESC;

 

image

Voila.. und das ist unser Ergebnis. vermutlich hatte alles was mit Sharepoint zu tun Zwinkerndes Smiley

Die Semantik belastet natürlich unseren Volltext ein Stück mehr, aber die Möglichkeiten, die sich daraus ergeben sind unerschöpfllich, vor allem, wenn man bendekt wie extrem schnel ldie Volltextindizierung geworden ist.

G Serie jetzt auch in der Region Us East 2 verfügbar

Nach der Region US West sind die neuen virtuellen Maschinen der G-Serie nun auch im Rechenzentrum US-Ost öffentlich verfügbar. Sie bieten mehr Speicher und mehr SSD-Speicherplatten als die bisher verfügbaren Azure virtuellen Maschinen. Außerdem sind Sie mit dem neuen Intel Xeon Processor E3 bestückt. Die G-Serie ist in fünf unterschiedlichen Instanzen G1-G5 verfügbar beginnend bei 2 Kernen 28 GB RAM und 412 GB SSD bis hin zur stärksten Maschine mit 32 Kernen, 448 GB RAM und 6.596 GB SSD-Platte. Die Preise hierzu finden Sie unter http://azure.microsoft.com/en-us/pricing/details/virtual-machines/.

Passend dazu bietet die ppedv Kurse zum Entwickeln von Azurelösungen an. Mehr Infos finden Sie unter http://www.ppedv.de/schulung/kurse/Azure-CloudAnwendungenentwickeln.aspx.

Statistisch semantische Suche

Ja richtig gehört: Statistisch semantische Suche. Ein schönes Wort. In Wikipedia liest man dazu “.. Bedeutung sprachlicher Zeichen..”  Und das triffts auch schon fast. Die statistisch semantische Suche extrahiert relevante Phrasen per Volltextsuche aus Spalten oder Filetables und gewichtet diese.

imageimage

Sehen wir uns mal gewichtete Phrasen eines Dokuments an.

Man ganz gut erkennen, dass hier in einem Dokument folgende Begriffe gefunden wurden und je nach Score der eine wohl wichtiger (häufiger) zu sein scheint, als ein anderer. In diesem Beispiel geht es also wohl um Workflows, Stichwörter und Sharepoint.

Tatsächlich muss der Begriff nicht als einzelnes Wort vorkommen, sondern durchaus in Kombinationen. In diesen Text geht es beispielsweise auch um Unternehmensstichwörter.

Aber wie kommt die statistisch semantische Suche in den SQL Server?

Dazu brauchts ein ordentliches Rezept mit folgenden Zutaten: Eine Semantikdatenbank, evtl. das Microsoft Office Filter Paket, die Volltextsuche, ein wenig TSQL und einen Neustart der Volltextsuche.

Punkt 1: Semantikdatenbank einbinden

Auf der DVD des SQL Servers findet sich im Verzeichnis \1031_DEU_LP\x64\Setup die Installationsdatei SemanticLanguageDatabase.msi für die Datenbank. Das Setup entpackt lediglich die Datenbank in ein Verzeichnis. Um die Semantikdatenbank in die SQL Serverinstanz einzubinden, muss die Datenbank noch angefügt werden. Entweder per GUI im SSMS oder per Script. Anschließend die Datenbank für die semantische Suche registrieren.

Punkt 2: Office Filter Paket einbinden

Da SQL Server keine aktuellen Office Versionen out-of-the-box supportet,  kann man das schnell ändern indem man sich das Office Filter Paket 2010 downloaded: http://www.microsoft.com/de-de/download/details.aspx?id=17062. Nach der Installation muss das Filterpaket noch der Volltextsuche bekannt gemacht werden

--SemantikDb DB extrahieren (\1031_DEU_LP\x64\Setup) --und attachen.....msi-File CREATE DATABASE semanticsdb ON (FILENAME = 'C:\Microsoft Semantic Language Database\semanticsdb.mdf') FOR ATTACH -- und registrieren EXEC sp_fulltext_semantic_register_language_statistics_db @dbname = N'semanticsdb'; --Welche Sprachen werden unterstützt select * from sys.fulltext_semantic_languages --Filterpackage installiert?? Exsitiert für Office 2007 und Office 2010 --Aktivieren der iFilter für Volltextsuche Sp_fulltext_service 'Load_os_resources', 1 --Anzeige der indizierbaren Dokumente select * from sys.fulltext_document_types

 

Nun Steht die Volltextsuche inkl semantischer Suche voll zur Verfügung. 

image

In den Volltexteigenschaften der Tabelle nur noch Häkchen setzten und den richtigen Typ wählen.

File_type für den Inhalt der Dokumente. In diesem Screenshot handelt es sich um eine Filetable.

 

image

SASS Mixins für CSS3 Media Queries

Im heutigen WebDesign Zeitalter ist es so gut wie unvorstellbar geworden ohne CSS PreCompiler oder gar CSS3 zu leben. CSS3 bietet einen enormen Funktions als auch Design Umfang wie z. B. Animationen, Transitions (übergangs Animationen), 3D Darstellun uvvvvm. Die CSS PreCompiler hingegen erweitern nicht die Möglichkeiten von CSS oder fügen gar neue Design möglichkeiten hinzu, sondern sie erweitern die CSS-Syntax. Dies ermöglicht uns nun mit Variablen, Funktionen, Ableitungen und derartigen Möglichkeiten unsere geschriebenen CSS Regeln oder Files wieder zu verwenden um uns somit unzählige graue Haare zu ersparen. Zu alle dem kommt noch die SmartPhone Ära hinzu (AlwaysOn), diese verlangt von uns WebEntwicklern –/ Designern die Layouts welche wir erstellen nun auch noch Responsive (empfänglich für diverse Browserauflösungen) zu erstellen.

Zu diesem Thema habe ich mir ein wenig Gedanken gemacht und das kam dabei heraus:

Die Mixins

   1: @mixin xs-media ($target: all){
   2:   @media #{$target} and (max-width: 360px) {
   3:     @content;
   4:   }
   5: }
   6:  
   7: @mixin sm-media ($target: all){
   8:   @media #{$target} and (min-width: 361px) and (max-width: 767px) {
   9:     @content;
  10:   }
  11: }
  12:  
  13: @mixin md-media ($target: all){
  14:   @media #{$target} and (min-width: 768px) and (max-width: 991px) {
  15:     @content;
  16:   }
  17: }
  18:  
  19: @mixin lg-media ($target: all){
  20:   @media #{$target} and (min-width: 992px) and (max-width: 1199px) {
  21:     @content;
  22:   }
  23: }
  24:  
  25: @mixin xlg-media($target: all) {
  26:   @media #{$target} and (min-width: 1200px) {
  27:     @content;
  28:   }
  29: }

Diese Mixins sind weder großartig komplex, noch schwer nach zu vollziehen…. sie sind einfach nur NÜTZLICH. Ähnlich wie CodeSnipptes in VisualStudio. Diese 5 @Media Mixins erleichtern den Umgang mit MediaQueries für Responsive Layouts. Das erste Mixin (max-width; 360px) {} wird man jedoch nicht all zu häufig verwenden müssen, da es strengstens empfohlen ist diese sog. Responsive Layouts mit der ‘Mobile First’ Variante zu erstellen. D. h. man fängt mit dem Design für kleinere Geräte an und skalliert dann nach oben. Dies hat wieder mehrere Vorteile:

1. Man fokusiert sich auf das wichtigste, den CONTENT! Da man nicht viel Platz für sonstigen Schnick-Schnack hat.

2. Es ist ohne probleme möglich nach oben hin weiter bzw. bis zur unendlichkeit zu skalieren. Stichwort SmartTV’s mit einer 4K Auflösung z. B. Wobei solche Auflösungen z. Z. noch von den wenigsten unterstützt bzw. angepasst werden.

Anwendung

Wie man nun diese oben gezeigten SASS-Mixins verwendet sieht folgendermaßen aus:

   1: div {
   2:   /*Diese attribute treffen auf xs-screens zu*/
   3:   .
   4:   .
   5:   .
   6:   
   7:   @include sm-screen {...};
   8:   
   9:   @include md-screen {...};
  10:  
  11:   @include lg-screen {...};
  12:  
  13:   @include xlg-screen {...};
  14: }

Ich hoffe diese kleinen Helferlein werden euch bei der Erstellung von vielen Responsive Websites helfen und Spaß machen Smiley

Unter http://codepen.io/MT-WebDev/pen/XJgjqN gibt es noch ein Beispiel wie das ganze dann in der Realität aussehen könnte.

Falls nun euer/dein Interesse geweckt ist, schau doch mal auf http://ppedv.de/web vorbei. Dort lösst sich bestimmt der richtige Kurs finden!

Ansichten in SharePoint

Eine Ansicht bietet die Möglichkeit, Elemente einer Bibliothek oder Liste zu Filter, Sortieren oder in irgendeiner anderen Art und Weise zu bearbeiten. Im Grunde alle Arten die “Sicht” auf Daten unseren Bedürfnissen anzupassen.

Dabei stehen uns Grundlegend ein paar Formate zur Verfügung:

Die Standartansicht

In 95% aller Fälle benutzt, bietet sie die gängigsten Optionen zum Betrachten von Bibliotheken und Listen. Bei dieser Ansicht werden die einzelnen Elemente untereinander angezeigt.

Eine Standardansicht

 

Die Standartansicht mit erweiterten Ereignisserien

Besonders zu empfehlen, wenn man jede Instanz einer Ereignisserie sich anzeigen lassen möchte.

Standardansicht mit Terminserie

 

Kalenderansicht

Mit dieser Ansicht lassen sich Daten aus Listen bzw. Einträgen chronologisch Darstellen oder Datumsangaben visuell darstellen. Gerade für den Einsatz in Projektumgebungen oft verwendet, um einen Überblick über vergangene und kommende Ereignisse zu erhalten.

 Eine Kalenderansicht

 

Datenblatt

Diese Ansicht ist ähnlich einer EXCEL-Tabelle und auch vergleichbar mit der quick-edit Ansicht. Dadurch lassen sich viele Datensätze komfortable bearbeiten.

Eine Datenblattansicht

 

Gantt

Benannt nach Henry L. Gantt lassen sich mit dieser Ansicht Daten mithilfe von Balken so darstellen, dass eine Nachverfolgung des Verlaufes möglich ist. Diese Ansicht findet vor allem Verwendung in der Projektarbeit, um frühzeitig Probleme zu erkennen, wie zum Beispiel sich überlappende Aufgaben, welche aber einer Person zugeordnet sind.

Eine Gantt-Ansicht

Stand-alone DHCP-Server plus DHCP-Server in Domäne gleich Problem?!

Wenn man einen DHCP-Server betreibt, dann sollte dies bevorzugter Weise in einer Domäne geschehen – also mit dem DHCP-Server als Mitglied des Active Directory. Dort benötigt dieser eine Autorisierung, welche dafür sorgt, dass dieser Server dann auf eingehende Anfragen (DHCP Request) reagiert. Solange er nicht autorisiert ist, vergibt er auch keine Adressen. Soweit so gut.

Wenn man einen DHCP-Server NICHT in Active Directory integriert, kann man ihn auch nicht autorisieren, er verrichtet dennoch seine Dienste – bis er auf einen autorisierten Server trifft!

Dann nämlich wird der nicht autorisierte Server (der nicht Mitglied der Domäne ist) seinen Dienst einstellen und selbst wenn man ihn wieder manuell aktiviert sich sofort wieder abschalten.

dhcp_rogue_2

dhcp_rogue_1

Damit ist es also nicht so ohne Weiteres möglich, zwei DHCP-Server im selben Netz zu betreiben. Nun kann es aber sein, dass genau das gewünscht ist – weil die Server z.B. Adressen für unterschiedliche MAC-Adressen verteilen. Hier muss man also eingreifen und den nicht-autorisierten DHCP Server daran hindern, sich abzuschalten.

Das “Zauberwort” hier heißt “Rogue Detection” – und genau die muss deaktiviert werden.

Dies geht nicht über eine GUI, sondern muss über eine Registrierungswert geändert werden. Dieser heisst

KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DHCPServer\Parameters
\DisableRogueDetection

dhcp_rogue_3

Mittels des folgenden Aufrufs lässt sich der Eintrag recht schnell anlegen:

reg add HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\DHCPServer\Parameters /v DisableRogueDetection /t REG_DWORD /d 1

Dieser Schlüssel ist sehr oberflächlich in folgendem KB-Artikel bei Microsoft beschrieben:

https://support.microsoft.com/kb/949530

Microsoft DNS-Server: Einträge massenweise “umziehen”

Wenn man mit einem Webserver zu einem anderen Provider wechselt oder aus sonstigen Gründen neue (öffentliche) IP Adressen zugewiesen bekommt, dann müssen natürlich auch die entsprechenden DNS-Einträge geändert werden. Wenn es sich hierbei nur um eine Hand voll handelt, könnte man dies auch manuell machen. Ab einer gewissen Menge ist das einfach nicht mehr praktikabel, da es a) zu lange dauert und b) auch sehr fehleranfällig wäre.

Als sinnvolle Lösung bietet sich hier die PowerShell an – vorausgesetzt, man hat einen Microsoft Windows Server als DNS-Server und auf diesem das entsprechende DNSServer Modul für die PowerShell verfügbar.

Das Skript, welches am Ende des Beitrages zum Download angeboten wird, sieht so aus:

<#
.Synopsis
   This script changes DNS A Records according to a CSV file - use at your own risk!
.DESCRIPTION
   This script changes DNS A Records according to a CSV file.

   The csv file should look like this:

   "OldIP","NewIP"
    "1.2.3.4","5.6.7.8"
    "2.4.6.8","1.3.5.7"

    to change all DNS records with "1.2.3.4" as value for "5.6.7.8" and "2.4.6.8" for "1.3.5.7"

.EXAMPLE
   Replace-DNSServerRecords.ps1 -CSVFile H:\OldAndNewIps.txt

   Replaces the DNS A records on the localhost DNS server according to the CSV-File H:\OldAndNewIps.txt
.EXAMPLE
   Replace-DNSServerRecords.ps1 -CSVFile H:\OldAndNewIps.txt -DNSServer mydns.domain.local -Verbose

   Replaces the DNS A records on the DNS server "mydns.domain.local" according to the CSV-File H:\OldAndNewIps.txt and writes verbose output
#>

Param(
    [Parameter(Mandatory=$True)]
    [ValidateScript({Test-Path $_ -PathType 'Leaf'})]
    [string]$CSVFile,
    [string]$DNSServer = "localhost"
)

Write-Warning "This script will possibly change a lot of DNS records. If you wish to cancel, press [CTRL]+[C], otherwise press [Enter]!"
Read-Host

# just in case of old PowerShell
Import-Module DNSServer

$CSVData = Import-CSV $CSVFile

$OldDNSRecordData = $CSVData.OldIP
$NewDNSRecordData = $CSVData.NewIP

$AllDNSZones = (Get-DnsServerZone -ComputerName $DNSServer | Where-Object IsReverseLookupZone -eq $False).ZoneName

$TotalChanges = 0

ForEach($CurrentDNSZone in $AllDNSZones)
{

    Write-Verbose "Processing current zone $CurrentDNSZone..."

    $AllDNSARecordsInZone = Get-DnsServerResourceRecord -ZoneName $CurrentDNSZone -RRType A -ComputerName $DNSServer
    Write-Verbose "Found $(($AllDNSARecordsInZone | Measure-Object).Count) DNS Records in current Zone"    

    ForEach ($CurrentRecord in $AllDNSARecordsInZone) {

        for($i=0; $i -lt $OldDNSRecordData.Length; $i++){

            If($CurrentRecord.RecordData.IPv4Address -eq $OldDNSRecordData[$i]) {

                Write-Verbose "Found an old DNS Record:"
                Write-Verbose "$($CurrentRecord.HostName) with $($CurrentRecord.RecordData.IPv4Address) in Zone $CurrentDNSZone"

                $NewRecord = $CurrentRecord.Clone()
                
                $NewRecord.RecordData.IPv4Address = $NewDNSRecordData[$i]

                Set-DnsServerResourceRecord -OldInputObject $CurrentRecord `
                                            -NewInputObject $NewRecord `
                                            -ZoneName $CurrentDNSZone `
                                            -ComputerName $DNSServer
                $TotalChanges++
            }
        }
    }
}

Write-Host "Changed Records: $TotalChanges"

 

Das Skript durchläuft alle Forward-DNS-Zonen und prüft dabei nacheinander alle vorhandene A-Records gegen die Liste der zu ändernden Einträge. Wenn ein entsprechender Eintrag gefunden wird, wird für diesen die IP-Adresse gegen die neue ausgetauscht. Am Ende gibt das Skript aus, wieviele Einträge insgesamt geändert wurden. Aus Sicherheitsgründen ist nach dem Start noch einmal zu bestätigen, dass das Skript seine Arbeit verrichten soll.

Das fertige Skript kann hier heruntergeladen werden:

Replace-DNSServerRecords.zip

Die Benutzung geschieht auf eigene Gefahr!

Sie wollen lernen, wie dieses Script im Detail funktioniert oder derartige Scripte selber schreiben? Dann besuchen Sie unseren PowerShell-Kurs!

Flexible Layouts: CSS3 Flexbox

Das Flexible Box Layout Module oder kurz Flexbox genannt, ist ein ausgesprochen mächtiges Layout-Modul in CSS3. Es ermöglicht vieles, was mit klassischem CSS gar nicht oder nur durch Tricksereien möglich wäre.

- Elemente beliebig mehrzeilig horizontal oder vertikal anordnen

- Anordnung der Elemente ganz genau steuern und den Leerraum auf verschiedene Arten verteilen

- Reihenfolge und Ausmaße der Elemente können beliebig bestimmt und flexibel festgelegt werden

Andererseits ist der Umgang mit dem Flexible Box Layout Modul auch relativ komplex. Schwierigkeiten können vor allem durch den unterschiedlichen Support in den verschiedenen Browsern entstehen, da sich die CSS Notation über die Jahre stark verändert hat. Die unterschiedlichen Schreibweisen sind hier angeführt.

- Aktuelle Syntax: display: flex;

- Hybrid Syntax 2011: display: flexbox;

- Alte Syntax 2009: display: box;

In der nachfolgenden Tabelle, von caniuse entlehnt, soll ein kurzer Überblick über den Browsersupport der aktuellen Flexbox Variante display: flex; gegeben werden.

Flexbox flex

Als Unterstützung in der Stylesheet Entwicklung bietet es sich an, Hilfsmittel wie beispielsweise einen Autopräfixer für ältere CSS Versionen zu verwenden, der automatisch den notwendigen Code erzeugt. Ein solches Tool findet sich unter dem nachfolgenden Link:

http://jsbin.com/gufoko/quiet 

In diesem Blogbeitrag widmen wir uns der aktuellen Flexbox Variante in CSS3. Bei der Arbeit mit dem CSS Flexible Box Layout wird ein eigenes Vokabular verwendet. Als Flexcontainer wird das umfassende Element bezeichnet, indem sich die sogenannten Flexitems befinden. .Die Steuerung und Ausrichtung der einzelnen Elemente erfolgt schließlich über CSS Klassen. Das anschließende Codesegment soll einen kurzen Überblick geben. Hier werden die Flexitems innerhalb des Flexcontainers automatisch nebeneinander angeordnet und sind gleich hoch.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Flexbox Beispiel</title>
    <style>
        p {
            padding: 2em;
            color: white;
            font-family: sans-serif;
        }
        .uno {
            background-color:red;
        }
        .due {
            background-color:gold;
        }
        .tre {
            background-color:green;
        }
        .flexbox {
            /* Starten der Flexbox */
            display: flex;
        }
    </style>
</head>
<body>
    <div class="flexbox">
        <p class="uno">Uno</p>
        <p class="due">Due</p>
        <p class="tre">Tre</p>
    </div>
</body>
</html>

 

Das Flexbox-Ergebnis sieht schließlich so aus, dass die Kind Elemente nebeneinander angeordnet werden und die gleiche Höhe haben.

Flexbox

Standardmäßig ist hier das Attribut flex-direction: row vorausgewählt. Um die Elemente untereinander anzuordnen, muss hier die CSS Eigenschaft flex-direction: column gewählt werden. Ein weiterführendes Beispiel zum Thema Flexbox finden Sie im untenstehenden Link.

http://jsfiddle.net/kkonstantin/8o03s30e/

Wenn Sie mehr zum Thema Möglichkeiten der Verwendung von CSS3 und Responsive Design erfahren möchten, raten wir zur aktuellen Schulung: Responsive Design mit CSS3. Viel Spaß und gutes Gelingen beim Ausprobieren des CSS Flexible Box Layout Moduls!

Windows 10 – der nächste Schritt

Windows 10 ist bereits seit längerem in diversen Preview-Version erhältlich und soll im Laufe diesen Jahres endgültig freigegeben werden. Auf dem Weg dorthin hat Microsoft für den 21. Januar 2015 eine Pressekonferenz angekündigt, auf der einige Neuigkeiten zu Windows 10, verbunden mit der nächsten Vorab-Version, bekannt gegeben werden. Die Pressekonferenz startet 09:00 PST, was 18:00 Deutscher Zeit entspricht. Sie kann online unter folgender Adresse verfolgt werden:

http://news.microsoft.com/windows10story/

Mit etwas Glück werden auch Neuigkeiten zum Windows Server 2015 / vNext bekannt gegeben oder gar eine neue Preview veröffentlicht. Es bleibt also spannend!

ASP.NET Webforms Custom Controls

Seit Ewigkeiten habe ich keine Web Forms Controls mehr geschrieben. Mit Angular.JS Direktiven wird HTML erweitert und man erhält funktionell ein HTML Control. Das kann man natürlich auch Server gerendert, mit ASP.NET.

Die Programmieraufgabe lautet ein Validierungs Control selber zu schreiben. Eine übliche Aufgabe ist ein Prompt der die Daten eventuell noch einmal anzeigt und per JA und Nein bestätigt werden kann.

Dafür benötigt man allerdings einen Mix aus Server und Client Code. Um eine einheitliche Programmier Experience zu haben, wird JavaScript um eine String.format Funktion ala .net erweitert. Das ist geklauter Code, oder wie man auch gerne sagt Open Source.

   1:   String.format = function () {
   2:              var theString = arguments[0];
   3:   
   4:              for (var i = 1; i < arguments.length; i++) {
   5:                  // "gm" = RegEx options for Global search (more than one instance)
   6:                  // and for Multiline search
   7:                  var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm");
   8:                  theString = theString.replace(regEx, arguments[i]);
   9:              }
  10:              return theString;

 

Als nächstes wird eine Klasse von CustomValidator geerbt. Im Kern muss nur die Prerender Methode überschrieben werden, die HTML und JavaScript in den Client rendert.

   1:  Imports System.ComponentModel
   2:   
   3:  <DefaultProperty("PromptMessage")>
   4:  Public NotInheritable Class PromptValidator
   5:      Inherits CustomValidator
   6:      <DefaultValue("")>
   7:      Public Property PromptMessage() As String
   8:   
   9:   
  10:      Protected Overrides Sub OnPreRender(e As EventArgs)
  11:          Dim message = String.Concat("""", Me.PromptMessage, """")
  12:   
  13:          If PromptMessage.Contains("{0}") AndAlso Me.ControlToValidate <> "" Then
  14:              message = String.Concat("String.format(""", Me.PromptMessage, """, args.Value)")
  15:          End If
  16:   
  17:          Me.ClientValidationFunction = String.Concat("
new Function('sender', 'args', 'args.IsValid = confirm("
, message, ")')")
  18:          Me.EnableClientScript = True
  19:          MyBase.OnPreRender(e)
  20:      End Sub

 

Bereits ab diesem Zeitpunkt  befindet sich das neue Control in der Werkzeugleiste von Visual Studio und kann per Drag&Drop auf das Web Formular gezogen werden.

image

Auch wenn der Designer nicht perfekt ist, zeigt er das Steuerlement korrekt an. Im Quellecode kann man das registrierte Präfix erkennen.

   1:  <%@ Register Assembly="WebApplication5" Namespace="WebApplication5" TagPrefix="ppedv" %>
   2:  <html xmlns="http://www.w3.org/1999/xhtml">
   3:  <head runat="server">
   4:  ...    </head>
   5:   
   6:  <body>
   7:  <form id="form1" runat="server">
   8:  <asp:TextBox runat="server" ID="text1"></asp:TextBox>
   9:  <ppedv:PromptValidator runat="server" PromptMessage="Ihr Wert {0}?"
  10:           ErrorMessage="Ganz falsch" ControlToValidate="text1" 
  11:          ValidateEmptyText="true"/>
  12:          

Profis werden Ihre Controls in Assemblys kompilieren und das registrieren zentral in der web.config vornehmen. Alles in allem trotz fehlender Übung schnell und einfach von der Hand gegangen.

Übrigens werden Web Forms Schulungen noch immer gebucht.

Training, Schulung, Sharepoint

Month List