{"id":55000134,"date":"2018-04-01T00:00:00","date_gmt":"2020-03-27T19:32:24","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=134"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"ASPNET_Core_Validierung","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/ASPNET_Core_Validierung\/","title":{"rendered":"ASP.NET Core: Validierung"},"content":{"rendered":"<p><b>Genau wie in Desktop-Anwendung ist auch in Webanwendungen die Validierung der Benutzereingaben ein wichtiges Feature. Unter ASP.NET Core gibt es f&uuml;r die Razor Pages erfreulicherweise eine Standardvorgehensweise, die wir in diesem Artikel vorstellen werden. <\/b><\/p>\n<h2>Vorbereitung<\/h2>\n<p>F&uuml;r das Nachvollziehen der Beispiele in diesem Artikel legen Sie in Visual Studio 2017 ein neues Projekt namens Validierung an. Es wird mit der Projektvorlage <b>VisualC#|Web|ASP.NET Core Webanwendung <\/b>erstellt. Im zweiten Vorlagendialog w&auml;hlen Sie dann den Typ <b>Webanwendung <\/b>aus. Wir wollen die Seite <b>Pages\/Customers\/Create.cshtml <\/b>nutzen, um unsere Beispiele auszuprobieren. Diese wollen wir &uuml;ber einen neuen Men&uuml;eintrag der Webanwendung aufrufen, den wir in der Datei <b>_Layout.cs <\/b>einf&uuml;gen, und zwar an dieser Stelle:<\/p>\n<pre>...\r\n&lt;div class=\"navbar-collapse collapse\"&gt;\r\n     &lt;ul class=\"nav navbar-nav\"&gt;\r\n         &lt;li&gt;&lt;a asp-page=\"\/Index\"&gt;Home&lt;\/a&gt;&lt;\/li&gt;\r\n         &lt;li&gt;&lt;a asp-page=\"\/About\"&gt;About&lt;\/a&gt;&lt;\/li&gt;\r\n         &lt;li&gt;&lt;a asp-page=\"\/Customers\/Create\"&gt;Neuer Kunde&lt;\/a&gt;&lt;\/li&gt;\r\n     &lt;\/ul&gt;\r\n&lt;\/div&gt;\r\n...<\/pre>\n<p>Insgesamt werden wir neben &Auml;nderung der Datei <b>_Layout.cs <\/b>noch zwei Dateien samt Verzeichnissen hinzuf&uuml;gen, n&auml;mlich <b>Models\/Customer.cs <\/b>und <b>Pages\/Customers\/Create.cshtml <\/b>(siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_02\/pic_134_003.png\" alt=\"Anlage einiger Verzeichnisse und Dateien\" width=\"499,6607\" height=\"575,9685\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Anlage einiger Verzeichnisse und Dateien<\/span><\/b><\/p>\n<h2>Grundlagen<\/h2>\n<p>In Webanwendungen landen die Daten aus Tabellen zun&auml;chst in einem Objekt auf Basis einer Klasse, bevor diese auf einer Webseite dargestellt werden &#8211; diese Vorgehensweise kennen Sie ja auch schon von den Artikeln &uuml;ber den Einsatz des Entity Frameworks in Desktop-Anwendungen. Der Vorteil dieser Vorgehensweise ist, dass die Validierungsregeln nur an einer Stelle angelegt werden m&uuml;ssen und nicht etwa auf jeder Seite, welche die Eingabe oder Bearbeitung der Daten der betroffenen Klasse erlauben soll. Die Validierungsregeln werden hier wie da direkt in den Klassen angelegt, welche die Tabellen der Datenbank repr&auml;sentieren. Dazu legen wir zu Beispielzwecken diesmal keine Klasse auf Basis einer Tabelle an, sondern eine einfache Klasse ohne Bindung an eine Datenbank.<\/p>\n<p>Zu Beispielzwecken legen wir nun eine Klasse namens <b>Customers.cs <\/b>an, und zwar in einem zuvor erstellten Verzeichnis namens Models direkt unterhalb des Projektordners. Dort w&auml;hlen Sie dann den Kontextmen&uuml;-Eintrag <b>Hinzuf&uuml;gen|Klasse&#8230; <\/b>aus und geben im nun erscheinenden Dialog <b>Neues Element hinzuf&uuml;gen <\/b>den Namen f&uuml;r die Klasse ein &#8211; hier <b>Customer.cs <\/b>(siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_02\/pic_134_001.png\" alt=\"Hinzuf&uuml;gen einer Klasse zum Verwalten von Kunden\" width=\"649,559\" height=\"366,1\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Hinzuf&uuml;gen einer Klasse zum Verwalten von Kunden<\/span><\/b><\/p>\n<p>Die Klassendatei mit der Klasse <b>Customer<\/b> erg&auml;nzen wir nun wie in folgendem Code um einige Beispielfelder. Wozu das Feld namens <b>Rating <\/b>dient Es hat einen bestimmten Zweck &#8211; au&szlig;er als Beispiel f&uuml;r ein <b>Decimal<\/b>-Feld &#8230;<\/p>\n<pre>public class Customer {\r\n     public int ID { get; set; }\r\n     public string FirstName { get; set; }\r\n     public string LastName { get; set; }\r\n     public string Street { get; set; }\r\n     public string Zip { get; set; }\r\n     public string City { get; set; }\r\n     public string Email { get; set; }\r\n     public string Url{ get; set; }\r\n     public string Phone { get; set; }\r\n     public DateTime Birthday { get; set; }\r\n     public decimal Rating { get; set; }\r\n}<\/pre>\n<p>Wenn wir nun ein Formular auf Basis dieser Daten anlegen, sieht dies wie in gek&uuml;rzter Form wie folgt aus:<\/p>\n<pre>@page\r\n@model Validierung.Pages.Customers.CreateModel\r\n@{ ViewData[\"Title\"] = \"Create\"; }\r\n&lt;h2&gt;Datensatz erstellen&lt;\/h2&gt;\r\n&lt;div class=\"row\"&gt;\r\n     &lt;div class=\"col-md-4\"&gt;\r\n         &lt;form method=\"post\"&gt;\r\n             &lt;div asp-validation-summary=\"ModelOnly\" class=\"text-danger\"&gt;&lt;\/div&gt;\r\n             &lt;div class=\"form-group\"&gt;\r\n                 &lt;label class=\"control-label\"&gt;Vorname:&lt;\/label&gt;\r\n                 &lt;input asp-for=\"Customer.FirstName\" class=\"form-control\" \/&gt;\r\n                 &lt;span asp-validation-for=\"Customer.FirstName\" class=\"text-danger\"&gt;&lt;\/span&gt;\r\n             &lt;\/div&gt;\r\n             ...\r\n             &lt;div class=\"form-group\"&gt;\r\n                 &lt;input type=\"submit\" value=\"Create\" class=\"btn btn-default\" \/&gt;\r\n             &lt;\/div&gt;\r\n         &lt;\/form&gt;\r\n     &lt;\/div&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>Wir sehen hier im oberen Teil die Razor-Anweisungen, mit denen unter anderem die Klasse <b>Validierung.Pages.Customers.CreateModel <\/b>als Modell referenziert wird. Darunter folgen einige Elemente samt <b>form<\/b>-Element. Die f&uuml;r die Validierung wichtigen Elemente sind das Element mit dem Attribut <b>asp-validation-summary <\/b>&uuml;ber den &uuml;brigen Elementen sowie das Element mit dem Attribut <b>asp-validation-for <\/b>f&uuml;r jedes einzelne Steuer-element, das an eines der Felder der Modell-Klasse gebunden ist.<\/p>\n<p>Bevor wir auf diese eingehen, schauen wir uns noch an, wie wir die Klasse mit ein paar Validierungen ausstatten und wie das <b>PageModel <\/b>und das Model f&uuml;r die Seite aussehen.<\/p>\n<h2>Model der HTML-Seite<\/h2>\n<p>Die Code behind-Datei enth&auml;lt den folgenden Code, unter anderem mit dem <b>PageModel<\/b>:<\/p>\n<pre>... weitere Namespace-Referenzen\r\nusing Validierung.Models;\r\nnamespace Validierung.Pages.Customers {\r\n     public class CreateModel : PageModel {\r\n         public IActionResult OnGet() {\r\n             return Page();\r\n         }\r\n         [BindProperty]\r\n         public Customer Customer { get; set; }\r\n         public IActionResult OnPost() {\r\n             if (!ModelState.IsValid) {\r\n                 return Page();\r\n             }\r\n             return RedirectToPage(\".\/Index\");\r\n         }\r\n     }\r\n}<\/pre>\n<p>Hier definieren wir einen Verweis auf das Verzeichnis Entit&auml;ten, also <b>Validierung.Models<\/b>.  Dann f&uuml;gen wir eine <b>OnGet<\/b>-Methode ein, welche beim Aufruf die auf Basis von <b>Create.cshtml <\/b>zusammengestellt Seite zur&uuml;ckliefert. Wir binden die Seite an die Klasse <b>Customer <\/b>als Model. Dazu versehen wir die &ouml;ffentliche Variable <b>Customer <\/b>des Typs <b>Customer <\/b>mit dem Attribut <b>[BindProperty]<\/b>. Interessant ist die Methode <b>OnPost<\/b>, die letztlich die Validierung ausf&uuml;hrt &#8211; und zwar durch die Methode <b>IsValid <\/b>des Objekts <b>ModelState<\/b>. Liefert dieses nicht das Ergebnis <b>True<\/b>, wird wieder die Seite mit dem zuvor ausgef&uuml;llten Formular zur&uuml;ckgeliefert. Erst wenn <b>IsValid <\/b>den Wert <b>True <\/b>liefert, zeigt die Webanwendung die dann vorgesehene Seite an &#8211; in diesem Fall die <b>Index<\/b>-Seite. Das Objekt <b>ModelState <\/b>ist &uuml;brigens ein Element des Namespaces <b>Microsoft.AspNetCore.MVC<\/b>. Wenn die Methode <b>IsValid <\/b>von <b>ModelState <\/b>aufgerufen wird, untersucht die Webanwendung, ob die im Model <b>Customer <\/b>festgelegten Validierungsregeln erf&uuml;llt sind. Diese m&uuml;ssen wir allerdings erst noch hinzuf&uuml;gen.<\/p>\n<h2>Validierungsregeln in das Model einf&uuml;gen<\/h2>\n<p>Um dem Model, also der Klasse <b>Customer.cs<\/b>, die Validierungsregeln hinzuzuf&uuml;gen, m&uuml;ssen wir zun&auml;chst den Namespace <b>System.ComponentModel.DataAnnotations <\/b>hinzuf&uuml;gen:<\/p>\n<pre>using System.ComponentModel.DataAnnotations;<\/pre>\n<h2>Validierungsregel f&uuml;r Pflichtangaben<\/h2>\n<p>Die meistgenutzte Validierungsregel d&uuml;rfte die sein, die pr&uuml;ft, ob erforderliche Werte angegeben wurden. Um ein Feld in der Klasse <b>Customer <\/b>mit dieser Validierungsregel zu belegen, f&uuml;gen wir vor dem jeweiligen Feld die Data Annotation namens <b>Requery <\/b>ein &#8211; hier an einigen Beispielen zu sehen:<\/p>\n<pre>public class Customer {\r\n     public int ID { get; set; }\r\n     [Required]\r\n     public string FirstName { get; set; }\r\n     [Required]\r\n     public string LastName { get; set; }\r\n     [Required]\r\n     public string Street { get; set; }\r\n     ...\r\n}<\/pre>\n<p>Wenn wir die Anwendung nun starten, &uuml;ber den Men&uuml;eintrag <b>Neuer Kunde <\/b>zur Seite <b>Create.cshtml <\/b>wechseln und dort direkt auf die Schaltfl&auml;che mit der Beschriftung <b>Create <\/b>klicken, erhalten wir die Validierungsmeldungen aus Bild 3. Es klappt also alles wie gew&uuml;nscht. Nun schauen wir uns weitere M&ouml;glichkeiten an.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_02\/pic_134_002.png\" alt=\"Validierungsmeldungen\" width=\"424,7115\" height=\"874,4555\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Validierungsmeldungen<\/span><\/b><\/p>\n<h2>Tag Helper f&uuml;r die Validierung<\/h2>\n<p>Bei <b>asp-validation-summary <\/b>und <b>asp-validation-for <\/b>handelt es sich um sogenannte Tag-Helper (mehr Tag-Helper stellen wir im Artikel <b>ASP.NET Core: Tag Helper <\/b>vor). Der Tag Helper <b>asp-validation-summary <\/b>wird in der Regel einmal oberhalb eines Formulars angegeben. Dort hat er die Aufgabe, eventuell auftretende Validierungshinweise auszugeben, die nicht nur ein spezielles Feld betreffen, sondern mehrere Felder oder allgemeine Hinweise. F&uuml;r dieses Attribut gibt es drei m&ouml;gliche Werte:<\/p>\n<ul>\n<li><b>All<\/b><\/li>\n<li><b>ModelOnly<\/b><\/li>\n<li><b>None<\/b><\/li>\n<\/ul>\n<p>F&uuml;r <b>asp-validation-summary <\/b>ist aktuell der Wert <b>ModelOnly <\/b>festgelegt. Wir k&ouml;nnten diesen Wert einmal &auml;ndern in <b>All<\/b> und schauen uns an, was geschieht, wenn wir das Formular erneut ohne F&uuml;llen eines der Felder absenden (siehe Bild 4):<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_02\/pic_134_004.png\" alt=\"Validierungsmeldungen zusammengefasst im Kopfbereich\" width=\"424,7115\" height=\"522,5945\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Validierungsmeldungen zusammengefasst im Kopfbereich<\/span><\/b><\/p>\n<pre>&lt;div asp-validation-summary=\"All\" class=\"text-danger\"&gt;&lt;\/div&gt;<\/pre>\n<p>Es erscheint also schon vor dem Feld <b>Vorname<\/b> eine &Uuml;bersicht aller fehlerhaft ausgef&uuml;llten Eingabefelder. Das ist ehrlich gesagt nicht notwendig, wenn schon jedes einzelne Feld mit einem entsprechenden Text ausgestattet wird. Leider sind diese Texte auch noch in englischer Sprache &#8211; wir schauen uns also gleich an, wie Sie hier die deutschen Texte angeben k&ouml;nnen.<\/p>\n<p>Wozu aber dient dann die Einstellung <b>ModelOnly<\/b> Auch dieses hat seine Berechtigung, warum, sehen wir uns ebenfalls weiter unten an.<\/p>\n<h2>Validierungstexte in Deutsch<\/h2>\n<p>Die Validierungstexte k&ouml;nnen Sie direkt in den DataAnnotation-Elementen f&uuml;r die einzelnen Felder erg&auml;nzen, und zwar f&uuml;r das Element <b>Required<\/b>. Diesem f&uuml;gen Sie in Klammern noch den Parameter <b>ErrorMessage <\/b>mit dem gew&uuml;nschten Text hinzu.<\/p>\n<p>Die Meldungen werden dann sowohl im Kontext mit den einzelnen Textfeldern als auch in der &Uuml;bersicht der Validierungsmeldungen in der gew&uuml;nschten Form ausgegeben (siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_02\/pic_134_005.png\" alt=\"Deutsche Validierungsmeldungen\" width=\"424,7115\" height=\"470,0544\" \/><\/p>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000134\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000134?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000134\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"38e0d7a80c\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Genau wie in Desktop-Anwendung ist auch in Webanwendungen die Validierung der Benutzereingaben ein wichtiges Feature. Unter ASP.NET Core gibt es f&uuml;r die Razor Pages erfreulicherweise eine Standardvorgehensweise, die wir in diesem Artikel vorstellen werden. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66022018,662018,44000029,44000018,44000027,44000017],"tags":[],"yst_prominent_words":[],"class_list":["post-55000134","post","type-post","status-publish","format-standard","hentry","category-66022018","category-662018","category-Access_programmieren","category-ASPNET_Core","category-Excel_programmieren","category-WebApps_Razor_Pages"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000134"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000134\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000134"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}