Skip to main content

Model Binding and Validation

Level: Beginner to Intermediate

ℹ️ Where This Fits

Model binding converts HTTP request data into C# values. Validation checks whether that data is acceptable before your application processes it.

ℹ️ What You'll Learn
  • Model binding definition: Automatically convert HTTP request data into C# objects
  • Binding sources: Route parameters, Query strings (?className=10A), Request body (JSON)
  • Route binding: HttpGet captures id from URL path and binds to action parameter automatically
  • Query binding: public ActionResult GetStudents(string? className)?className=10A from query string
  • Body binding: [HttpPost] public ActionResult Create(Student student) → JSON body converted to Student object
  • [FromBody]: Explicit binding from request body (usually not needed, [ApiController] infers it)
  • [FromRoute]: Explicit binding from URL (rarely needed, inferred from action parameter)
  • [FromQuery]: Explicit binding from query string (needed when parameter name != property name)
  • Validation attributes: [Required], [StringLength(100)], [Range(1, 12)], [EmailAddress] on model properties
  • ModelState.IsValid: Check if all validation passed before processing (if invalid, return 400)
  • School Management examples: Create student needs Name (Required), RollNumber (format regex), ClassName (Range 1-12)
  • Complex objects: [HttpPost] CreateStudent(StudentCreateRequest request) with nested Address object
  • [ApiController] auto-validation: Returns 400 Bad Request automatically if ModelState invalid (no manual check needed!)
  • Common mistakes: Forgetting [Required] (allows null), not returning 400 on invalid input, complex nested validation
  • Common input validation mistakes

What is Model Binding?

HTTP requests are text-based.

Example:

POST /api/students
Content-Type: application/json

{
"name": "Anika",
"classNumber": 8,
"parentEmail": "parent@example.com"
}

Model binding converts this request into a C# object.

public IActionResult CreateStudent(CreateStudentRequest request)

ASP.NET Core creates CreateStudentRequest and fills its properties.

Where Data Can Come From

SourceExample
Route/api/students/101
Query string/api/students?classNumber=8
Request bodyJSON sent in POST/PUT
HeadersAuthorization, custom headers
Form dataHTML form submit

Route Binding

💻 Try It — Console App
💡 Route parameter name should match the action parameter name.⌥ GitHub
[HttpGet("{id}")]
public IActionResult GetStudent(int id)
{
return Ok(new { StudentId = id });
}

Request:

GET /api/students/101

Result:

id = 101

Query String Binding

[HttpGet]
public IActionResult SearchStudents(int classNumber, string? section)
{
return Ok(new
{
ClassNumber = classNumber,
Section = section
});
}

Request:

GET /api/students?classNumber=8&section=A

Result:

classNumber = 8
section = A

Request Body Binding

For POST and PUT APIs, data usually comes from JSON body.

[HttpPost]
public IActionResult CreateStudent(CreateStudentRequest request)
{
return Ok(request);
}

Request body:

{
"name": "Anika",
"classNumber": 8,
"rollNumber": 21,
"parentEmail": "parent@example.com"
}

DTO:

public class CreateStudentRequest
{
public string Name { get; set; } = string.Empty;
public int ClassNumber { get; set; }
public int RollNumber { get; set; }
public string ParentEmail { get; set; } = string.Empty;
}

Binding Attributes

You can be explicit about where data comes from.

[HttpGet("{id}")]
public IActionResult GetStudent(
[FromRoute] int id,
[FromQuery] bool includeAttendance)
{
return Ok();
}

Common attributes:

AttributeReads From
[FromRoute]Route values
[FromQuery]Query string
[FromBody]JSON body
[FromHeader]Request headers
[FromForm]Form data

What is Validation?

Validation checks whether input is acceptable.

Example business rules:

  • student name is required
  • class number must be between 1 and 12
  • parent email must be valid
  • date of birth cannot be in the future
  • roll number must be positive

Data Annotation Validation

using System.ComponentModel.DataAnnotations;

public class CreateStudentRequest
{
[Required]
[StringLength(100, MinimumLength = 2)]
public string Name { get; set; } = string.Empty;

[Range(1, 12)]
public int ClassNumber { get; set; }

[Range(1, 200)]
public int RollNumber { get; set; }

[Required]
[EmailAddress]
public string ParentEmail { get; set; } = string.Empty;
}

Common Validation Attributes

AttributePurpose
[Required]Value must be provided
[StringLength]Limits text length
[MinLength]Minimum length
[MaxLength]Maximum length
[Range]Number must be within range
[EmailAddress]Valid email format
[Phone]Valid phone format
[RegularExpression]Pattern matching

ModelState

ModelState stores binding and validation errors.

[HttpPost]
public IActionResult CreateStudent(CreateStudentRequest request)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var student = _studentService.CreateStudent(request);
return CreatedAtAction(nameof(GetStudent), new { id = student.Id }, student);
}

ApiController Automatic Validation

When a controller has [ApiController], ASP.NET Core automatically returns 400 Bad Request for invalid models.

[ApiController]
[Route("api/students")]
public class StudentsController : ControllerBase
{
[HttpPost]
public IActionResult CreateStudent(CreateStudentRequest request)
{
var student = _studentService.CreateStudent(request);
return Ok(student);
}
}

If validation fails, the action may not run at all.

Nullable Reference Types and Required

This is a clean DTO style:

public class CreateTeacherRequest
{
[Required]
public string Name { get; set; } = string.Empty;

[EmailAddress]
public string? Email { get; set; }
}

Use string.Empty for required strings when you want to avoid null warnings.

Use nullable string? when the value is optional.

Custom Validation Example

For simple custom rules, implement IValidatableObject.

public class CreateExamRequest : IValidatableObject
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }

public IEnumerable<ValidationResult> Validate(
ValidationContext validationContext)
{
if (EndDate < StartDate)
{
yield return new ValidationResult(
"End date cannot be before start date.",
new[] { nameof(EndDate) });
}
}
}

Business Validation vs Input Validation

Input validation checks request shape:

Name required
Email format valid
Class number between 1 and 12

Business validation checks rules:

Roll number already exists
Admission closed for this class
Student already paid this month's fee

Business validation usually belongs in services.

Common Mistakes

MistakeBetter Approach
Trusting client-side validation onlyAlways validate on server
Accepting database entities directlyUse request DTOs
Putting all validation in controllerKeep business rules in services
Forgetting [ApiController] behaviorKnow automatic 400 responses
Making every field required accidentallyUse nullable types for optional fields
Returning unclear validation errorsReturn useful messages

Practice Task

Create CreateTeacherRequest.

  1. Add required Name.
  2. Add required Subject.
  3. Add optional Email with [EmailAddress].
  4. Add ExperienceYears with [Range(0, 40)].
  5. Create a POST action that accepts this DTO.

Quick Recap

QuestionAnswer
What is model binding?Mapping request data to C# parameters/objects
Route value example?/students/101 -> id = 101
Body binding used for?JSON POST/PUT requests
Validation storage?ModelState
Automatic 400 feature?[ApiController]
🎯 Interview Favourite

Q: What is model binding and validation in ASP.NET Core?

Good Answer: "Model binding automatically maps HTTP request data from route values, query strings, headers, forms, or JSON body into action parameters and C# models. Validation checks those models using data annotations such as Required, Range, StringLength, and EmailAddress. Validation errors are stored in ModelState. With [ApiController], invalid models automatically return a 400 response. Server-side validation is required because client-side validation can be bypassed."

🤖Use AI to Learn Faster

Use ChatGPT, Claude, or Copilot to go deeper on Model Binding and Validation. Try these prompts:

  • "Explain model binding using route, query string, and JSON body examples."
  • "What is ModelState in ASP.NET Core?"
  • "How does ApiController automatic validation work?"
  • "Show me a validated DTO for student admission."

💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.

Next Article

-> Filters - Action, Result, Exception

nexcoding.in