What is model binding in ASP.NET Core Web API?
Model binding converts data from an HTTP request into action parameters or .NET objects. ASP.NET Core can bind values from route parameters, query strings, headers, form fields, and request bodies.
ASP.NET Core Web API interview questions covering DTOs, model binding, validation and API response design.
Open a question for the full answer, code and interview guidance.
Model binding converts data from an HTTP request into action parameters or .NET objects. ASP.NET Core can bind values from route parameters, query strings, headers, form fields, and request bodies.
These attributes explicitly tell ASP.NET Core where an action parameter should be obtained. FromRoute reads route values, FromQuery reads the query string, FromBody deserializes the request body, FromHeader reads an HTTP header, and FromForm reads form data.
ApiController applies conventions that infer common binding sources. Complex types are commonly inferred from the request body, route-matching parameters from route data, and other simple parameters may come from the query string.
The request body is a single stream and is normally deserialized once, so an API action should not define multiple independent FromBody parameters. Instead, create one request DTO containing all body values required by the operation.
ASP.NET Core uses configured input formatters to deserialize request content into .NET objects. JSON is the standard format for modern APIs and is handled by System.Text.Json by default.
A request DTO defines the input contract accepted by an API operation. It should contain only the fields the client is permitted and required to send for that use case.
A response DTO defines the representation returned to API clients. It allows the API to expose a stable, intentional contract instead of serializing database entities directly.
They can be the same for very simple contracts, but separate DTOs are usually clearer when the operations have different requirements. A create request may require fields that an update does not, while a response may contain server-generated identifiers and timestamps that clients must not submit.
Overposting occurs when a client can submit properties that the operation did not intend to let the client control. Binding persistence entities directly is a common cause because fields such as IsApproved, OwnerId, or IsAdmin may become writable unintentionally.
Validation checks whether incoming data satisfies the rules defined for the request contract. Data Annotation attributes such as Required, StringLength, Range, and EmailAddress can describe common validation rules.
ApiController automatically returns an HTTP 400 response for model-validation failures instead of requiring every action to manually check ModelState.IsValid.
ValidationProblemDetails is a standardized error representation used to describe validation failures. It contains fields associated with the Problem Details format plus a collection of validation errors.
ProblemDetails is a structured representation for HTTP API errors based on the Problem Details standard. Common members include type, title, status, detail, and instance.
ApiBehaviorOptions can customize the response produced when model validation fails. This is useful when an organization requires a consistent error envelope, correlation identifier, or additional metadata.
Custom validation handles rules that cannot be expressed adequately with simple built-in attributes. A model can implement IValidatableObject, a project can define a custom ValidationAttribute, or application-level validation can run in a service or validation component.
Perform database-dependent validation in the application or domain service rather than relying only on Data Annotations. For example, checking whether an email is already registered requires current application state.
ActionResult<T> allows an action to return either a typed success value or another ActionResult such as NotFound, BadRequest, or Forbid. It communicates the successful response type clearly while retaining flexible HTTP error handling.
IActionResult represents an HTTP action result without declaring a specific successful body type in the method signature. ActionResult<T> combines a known success type with the ability to return other HTTP results.
CreatedAtAction returns HTTP 201 Created and generates a Location header pointing to another action, typically the GET endpoint for the newly created resource. It can also include the created representation in the response body.
CreatedAtRoute returns HTTP 201 Created and builds the Location header from a named route rather than directly naming an action method.
A collection endpoint should return a predictable array or collection representation and an appropriate success status. For large datasets, the endpoint should support pagination rather than returning the entire table.
Set sensible defaults and enforce minimum and maximum values. Without a maximum page size, a client may accidentally or deliberately request an extremely large result set and create unnecessary database, memory, serialization, and network load.
Collection endpoints commonly accept optional query parameters for filters and sorting. Only supported fields and directions should be accepted rather than directly turning arbitrary client strings into database expressions.
A request for one specific resource normally returns 404 when that resource does not exist. A valid collection query that finds no matching records normally returns 200 with an empty collection rather than 404.
Use purpose-specific request and response DTOs instead of exposing persistence entities. Make binding sources clear, validate input at the API boundary, and keep database-dependent or domain validation in appropriate application services.