Ce produit n'est pas pris en charge par le site Datadog que vous avez sélectionné. ().
Cette page n'est pas encore disponible en français, sa traduction est en cours. Si vous avez des questions ou des retours sur notre projet de traduction actuel, n'hésitez pas à nous contacter.
Metadata
ID:csharp-best-practices/use-model-binding
Language: C#
Severity: Notice
Category: Best Practices
Description
This rule encourages developers to use model binding instead of directly accessing data from the request object, such as Request.Form or Request.Headers. Model binding provides a clean and declarative way to receive input data by mapping HTTP request data to strongly typed parameters or models in controller actions.
Using model binding improves code readability, reduces boilerplate parsing and validation logic, and leverages built-in framework features like automatic type conversion and validation attributes. It helps prevent errors related to manual data extraction and parsing, which can introduce bugs or security vulnerabilities if not handled carefully.
To comply with this rule, define a model class representing the expected input and use action method parameters with attributes like [FromForm] or [FromHeader] to bind incoming data automatically. For example, use public IActionResult Register([FromForm] UserRegistrationModel model) instead of manually reading from Request.Form. This approach ensures cleaner, safer, and more maintainable code.
Non-Compliant Code Examples
usingMicrosoft.AspNetCore.Mvc;usingSystem;usingSystem.Collections.Generic;namespaceMyApp.Controllers{publicclassUserController:Controller{ [HttpGet]publicIActionResultRegister(){returnView();}// NON-COMPLIANT: Direct access to Request.Headers [HttpPost]publicIActionResultRegister_NonCompliant(){// Noncompliant: Direct access to Request.Headersvarname=Request.Headers["X-User-Name"].ToString();varemail=Request.Headers["X-User-Email"].ToString();varpassword=Request.Headers["X-User-Password"].ToString();varbirthdateStr=Request.Headers["X-User-Birthdate"].ToString();// Manual parsing and error handlingif(!DateTime.TryParse(birthdateStr,outvarbirthdate)){returnBadRequest("Invalid birthdate");}// Manual validationif(string.IsNullOrEmpty(name)||string.IsNullOrEmpty(email)){returnBadRequest("Name and email are required");}// Process registration...returnOk($"User {name} registered successfully");}// COMPLIANT: Using FromHeader attribute (Recommended) [HttpPost("register-compliant")]publicIActionResultRegister_Compliant( [FromHeader(Name = "X-User-Name")]stringname, [FromHeader(Name = "X-User-Email")]stringemail, [FromHeader(Name = "X-User-Password")]stringpassword, [FromHeader(Name = "X-User-Birthdate")]DateTimebirthdate){// Automatic binding and type conversionif(!ModelState.IsValid){returnBadRequest(ModelState);}// Manual validation (or use Data Annotations)if(string.IsNullOrEmpty(name)||string.IsNullOrEmpty(email)){returnBadRequest("Name and email are required");}// Process registration...returnOk($"User {name} registered successfully");}}}
usingMicrosoft.AspNetCore.Mvc;usingSystem;usingSystem.Collections.Generic;namespaceMyApp.Controllers{publicclassUserController:Controller{ [HttpGet]publicIActionResultRegister(){returnView();} [HttpPost]publicIActionResultRegister_NonCompliant(){// Noncompliant: Direct access to Request.Formvarname=Request.Form["name"];varemail=Request.Form["email"];varpassword=Request.Form["password"];varbirthdateStr=Request.Form["birthdate"];// Manual parsing and error handlingif(!DateTime.TryParse(birthdateStr,outvarbirthdate)){returnBadRequest("Invalid birthdate");}// Manual validationif(string.IsNullOrEmpty(name)||string.IsNullOrEmpty(email)){returnBadRequest("Name and email are required");}// Process registration...returnOk($"User {name} registered successfully");}}}
Compliant Code Examples
usingMicrosoft.AspNetCore.Mvc;usingSystem;usingSystem.ComponentModel.DataAnnotations;namespaceMyApp.Controllers{// Model class for registrationpublicclassUserRegistrationModel{ [Required(ErrorMessage = "Name is required")] [StringLength(100, ErrorMessage = "Name cannot exceed 100 characters")]publicstringName{get;set;} [Required(ErrorMessage = "Email is required")] [EmailAddress(ErrorMessage = "Invalid email format")]publicstringEmail{get;set;} [Required(ErrorMessage = "Password is required")] [MinLength(6, ErrorMessage = "Password must be at least 6 characters")] [DataType(DataType.Password)]publicstringPassword{get;set;} [Required(ErrorMessage = "Birthdate is required")] [DataType(DataType.Date)]publicDateTimeBirthdate{get;set;}}publicclassUserController:Controller{ [HttpGet]publicIActionResultRegister(){returnView();}// COMPLIANT: Using Model Binding with [FromForm] [HttpPost]publicIActionResultRegister([FromForm]UserRegistrationModelmodel){// Automatic validation based on Data Annotationsif(!ModelState.IsValid){returnBadRequest(ModelState);}// Process registration with validated model// All type conversions are handled automatically// birthdate is already a DateTime, not a stringreturnOk($"User {model.Name} registered successfully");}// Alternative: If you want to return validation errors to a view [HttpPost("register-view")]publicIActionResultRegisterWithView([FromForm]UserRegistrationModelmodel){if(!ModelState.IsValid){// Return to view with validation errorsreturnView("Register",model);}// Process registration...TempData["SuccessMessage"]=$"User {model.Name} registered successfully";returnRedirectToAction("Success");}// Alternative: Using individual parameters (less common, but valid) [HttpPost("register-params")]publicIActionResultRegisterWithParameters( [FromForm]stringname, [FromForm]stringemail, [FromForm]stringpassword, [FromForm]DateTimebirthdate){// Manual validation needed with this approachif(string.IsNullOrEmpty(name)||string.IsNullOrEmpty(email)){returnBadRequest("Name and email are required");}if(!ModelState.IsValid){returnBadRequest(ModelState);}// Process registration...returnOk($"User {name} registered successfully");} [HttpGet("success")]publicIActionResultSuccess(){returnView();}}}
1
2
rulesets:- csharp-best-practices # Rules to enforce C# best practices.