Kurs:Täglich Model Binding Übungen und Schwachstellen:Hauptseite: Unterschied zwischen den Seiten

Aus ahrensburg.city
(Unterschied zwischen Seiten)
Zur Navigation springen Zur Suche springen
Die Seite wurde neu angelegt: „= Model Binding & Validation – ASP.NET Core MVC (Spickzettel) = == Standard-Model-Binding (Query, Route, Form) == <syntaxhighlight lang="csharp"> // Route mit optionalen Parametern (aus Query oder Route gebunden) [Route("buchladen/{buchid?}/{eingeloggt?}")] public IActionResult Index(int? buchid, bool? eingeloggt) { return Content($"Buch-ID: {buchid}, Eingeloggt: {eingeloggt}", "text/plain"); } // Route mit festem (required) Parameter (aus Route…“
 
// via Wikitext Extension for VSCode
 
Zeile 1: Zeile 1:
= Model Binding & Validation – ASP.NET Core MVC (Spickzettel) =
==Schwachstellen==
 
===Sprachmodell===
== Standard-Model-Binding (Query, Route, Form) ==
* [https://airiskdatabase.com AI Risk Database] – Eine Datenbank mit Risiken und Schwachstellen im Bereich Künstliche Intelligenz.
 
* [https://github.com/advisories GitHub CVE & Security Advisories] – Offizielle Sicherheitswarnungen und CVE-Meldungen von GitHub für Open-Source-Projekte.
<syntaxhighlight lang="csharp">
* [https://cve.mitre.org/ MITRE CVE Database] – Zentrale Datenbank für öffentlich bekannte Schwachstellen (Common Vulnerabilities and Exposures, CVE).
// Route mit optionalen Parametern (aus Query oder Route gebunden)
* [https://nvd.nist.gov/ National Vulnerability Database (NVD)] – Die US-amerikanische nationale Datenbank für Schwachstellen, gepflegt vom NIST.
[Route("buchladen/{buchid?}/{eingeloggt?}")]
* [https://www.cvedetails.com/ CVE Details] – Eine benutzerfreundliche Übersicht und Analyse von CVE-Einträgen.
public IActionResult Index(int? buchid, bool? eingeloggt)
* [https://www.exploit-db.com/ Exploit Database] – Sammlung von Exploits und Proof-of-Concept-Code für bekannte Schwachstellen.
{
* [https://www.securityfocus.com/vulnerabilities SecurityFocus Vulnerability Database] – Archiv von Schwachstellen und Sicherheitsmeldungen.
    return Content($"Buch-ID: {buchid}, Eingeloggt: {eingeloggt}", "text/plain");
* [https://www.openwall.com/lists/oss-security/ Open Source Security (oss-security)] – Mailingliste und Archiv zu Schwachstellen in Open-Source-Software.
}
* [https://vuldb.com VulDB] – Community-basierte Schwachstellendatenbank mit aktuellen Informationen und Analysen.
 
* [https://www.zerodayinitiative.com/advisories/published/ Zero Day Initiative Advisories] – Veröffentlichte Schwachstellen und Exploits aus dem Zero Day Initiative Programm.
// Route mit festem (required) Parameter (aus Route gebunden)
[Route("shop/buecher/{id}")]
public IActionResult Buch()
{
    int id = Convert.ToInt32(Request.RouteValues["id"]);
    return Content($"<h1>Buch-Shop {id}</h1>", "text/html");
}
</syntaxhighlight>
 
== [FromQuery] und [FromRoute] verwenden ==
 
<syntaxhighlight lang="csharp">
[Route("buchladen/{buchid?}/{eingeloggt?}")]
public IActionResult Index([FromQuery] int? buchid, [FromRoute] bool? eingeloggt)
{
    // Explizites Binding: buchid nur aus Query, eingeloggt nur aus Route
    return Content($"Buch-ID: {buchid}, Eingeloggt: {eingeloggt}");
}
</syntaxhighlight>
 
== Model Binding mit Modelklassen ==
 
<syntaxhighlight lang="csharp">
// Modelklasse
public class Buch
{
    public int? BuchId { get; set; }
    public string? Autor { get; set; }
    public override string ToString() => $"Buch: {BuchId}, Autor: {Autor}";
}
 
// Controller
[Route("buchladen/{buchid?}/{eingeloggt?}")]
public IActionResult Index([FromQuery] int? buchid, [FromRoute] bool? eingeloggt, Buch buch)
{
    return Content($"Buch-ID: {buchid}, Buch: {buch}", "text/plain");
}
</syntaxhighlight>
 
== Model Validation mit DataAnnotations ==
 
<syntaxhighlight lang="csharp">
using System.ComponentModel.DataAnnotations;
 
public class Person
{
    [Required(ErrorMessage = "{0} darf nicht leer sein")]
    public string? Name { get; set; }
 
    [EmailAddress]
    public string? Email { get; set; }
 
    [Compare("Passwort", ErrorMessage = "Passwörter stimmen nicht überein")]
    public string? PasswortBestätigung { get; set; }
}
 
// Controller
public IActionResult Erstellen(Person person)
{
    if (!ModelState.IsValid)
        return View(person);
    // Speicherung etc.
}
</syntaxhighlight>
 
== Custom Validation Attribute Beispiel ==
 
<syntaxhighlight lang="csharp">
// Validator: ToDate >= FromDate
public class DatumsbereichValidatorAttribute : ValidationAttribute
{
    public string VonProperty { get; }
    public DatumsbereichValidatorAttribute(string vonProperty) => VonProperty = vonProperty;
    protected override ValidationResult? IsValid(object? value, ValidationContext context)
    {
        if (value is DateTime toDate)
        {
            var fromProp = context.ObjectType.GetProperty(VonProperty);
            if (fromProp?.GetValue(context.ObjectInstance) is DateTime fromDate && fromDate > toDate)
                return new ValidationResult(ErrorMessage, new[] { VonProperty, context.MemberName! });
        }
        return ValidationResult.Success;
    }
}
</syntaxhighlight>
 
== Model-Level Validation mit IValidatableObject ==
 
<syntaxhighlight lang="csharp">
public class Person : IValidatableObject
{
    public DateTime? Geburtsdatum { get; set; }
    public int? Alter { get; set; }
 
    public IEnumerable<ValidationResult> Validate(ValidationContext context)
    {
        if (!Geburtsdatum.HasValue && !Alter.HasValue)
            yield return new ValidationResult("Geburtsdatum ODER Alter muss angegeben werden", new[] { nameof(Alter) });
    }
}
</syntaxhighlight>
 
== [Bind] und [BindNever] Attribute ==
 
<syntaxhighlight lang="csharp">
// Nur bestimmte Felder binden
[HttpPost]
public IActionResult Erstellen([Bind("Titel", "Beschreibung")] Produkt produkt) { ... }
 
// Niemals aus Request binden
public class Produkt
{
    [BindNever]
    public DateTime ErstelltAm { get; set; }
}
</syntaxhighlight>
 
== [FromBody]: JSON/XML Body-Parameter binden ==
 
<syntaxhighlight lang="csharp">
[Route("registrieren")]
public IActionResult Index([FromBody] Person person)
{
    if (!ModelState.IsValid) { ... }
    return Content($"{person}");
}
</syntaxhighlight>
 
== Collection Binding (Listen/Arrays binden) ==
 
<syntaxhighlight lang="csharp">
public class Person
{
    public List<string?> Interessen { get; set; } = new();
}
 
// JSON: { "Name": "Anna", "Interessen": ["Musik", "Lesen", "Coding"] }
public IActionResult Index(Person person)
{
    return Content($"Person: {person.Name}, Interessen: {string.Join(",", person.Interessen)}");
}
</syntaxhighlight>
 
== [FromHeader]: Parameter aus HTTP-Header ==
 
<syntaxhighlight lang="csharp">
[Route("registrieren")]
public IActionResult Index(Person person, [FromHeader(Name = "User-Agent")] string userAgent)
{
    return Content($"{person}, {userAgent}");
}
</syntaxhighlight>
 
== Input Formatters registrieren (z.B. XML) ==
 
<syntaxhighlight lang="csharp">
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddXmlSerializerFormatters();
</syntaxhighlight>
 
== Custom Model Binder registrieren ==
 
<syntaxhighlight lang="csharp">
// Custom Binder implementieren
public class PersonModelBinder : IModelBinder { ... }
 
// BinderProvider registrieren (Startup/Program.cs)
builder.Services.AddControllers(options => {
    options.ModelBinderProviders.Insert(0, new PersonBinderProvider());
});
</syntaxhighlight>
 
----
 
= Übungen / Mini-Aufgaben =
 
* Schreibe eine Controller-Methode, die einen Parameter aus der Query und einen aus der Route bindet.
* Erstelle ein Model mit mindestens drei Properties und validiere sie mit DataAnnotations.
* Schreibe ein Custom ValidationAttribute, das prüft, ob ein Datum in der Zukunft liegt.
* Nutze [FromBody], um ein komplettes Model aus JSON im Request-Body zu binden.
* Verwende [BindNever], um eine Eigenschaft vor Overposting zu schützen.
* Binde eine Liste von Strings im Model und fülle sie über ein Array im Request.
* Hole den User-Agent per [FromHeader] und gib ihn in der Response aus.

Version vom 24. Juni 2025, 15:18 Uhr

Schwachstellen

Sprachmodell