[HttpPost]
| Since: | ASP.NET Core 6(2021) |
|---|
The [HttpPost] attribute in ASP.NET Core indicates that a controller action method handles HTTP POST requests. Methods with this attribute respond to operations where the client sends data to the server, such as form submissions, creating new resources, and login processing.
Syntax
// Without a route template, maps to the controller's route
[HttpPost]
public ActionName()
{
// Write the implementation to handle POST requests here
}
// Specify a route template to set up an additional path segment
[HttpPost("template")]
public ActionName()
{
// Handles POST requests that match the template
}
// Add [FromBody] to receive the request body as a model
[HttpPost]
public ActionName([FromBody] ModelType model)
{
// The body sent as JSON etc. is automatically bound to the model
}
How to Receive Request Data
| Example | Description |
|---|---|
[FromBody] | Binds the request body (JSON, XML, etc.) to a model. Can be omitted when [ApiController] is applied, as it is automatically inferred. |
[FromForm] | Binds data sent via HTML form (application/x-www-form-urlencoded or multipart/form-data) to a model. |
[FromRoute] | Receives a URL path segment as a parameter. Corresponds to {parameterName} in the route template. |
[FromQuery] | Binds URL query parameters (?key=value). Can also be used with POST. |
[FromHeader] | Receives the value of an HTTP request header as a parameter. |
Sample Code
An example of defining a controller that registers a new product, handles validation errors, and returns the creation result using the [HttpPost] attribute.
// ProductsController.cs
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private static readonly List<Product> _products = new List<Product>
{
new Product { Id = 1, Name = "Apple", Price = 150, Category = "Fruit" },
new Product { Id = 2, Name = "Orange", Price = 100, Category = "Fruit" },
};
private static int _nextId = 3;
// POST api/products
[HttpPost]
public ActionResult<Product> Create([FromBody] ProductCreateRequest request)
{
// Because [ApiController] is applied, model validation is run automatically.
// If there are validation errors, 400 Bad Request is returned before reaching here.
var newProduct = new Product
{
Id = _nextId++,
Name = request.Name,
Price = request.Price,
Category = request.Category,
};
_products.Add(newProduct);
return CreatedAtAction(nameof(GetById), new { id = newProduct.Id }, newProduct);
}
// GET api/products/{id}
[HttpGet("{id:int}")]
public ActionResult<Product> GetById(int id)
{
var product = _products.Find(p => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int Price { get; set; }
public string Category { get; set; }
}
public class ProductCreateRequest
{
[Required(ErrorMessage = "Product name is required.")]
[StringLength(50, MinimumLength = 1, ErrorMessage = "Product name must be between 1 and 50 characters.")]
public string Name { get; set; }
[Range(1, int.MaxValue, ErrorMessage = "Price must be 1 or greater.")]
public int Price { get; set; }
[Required(ErrorMessage = "Category is required.")]
public string Category { get; set; }
}
Example requests and their expected responses.
// Successful registration request
// POST api/products
// Content-Type: application/json
// { "name": "Grape", "price": 300, "category": "Fruit" }
// → 201 Created
// Location: /api/products/3
// { "id": 3, "name": "Grape", "price": 300, "category": "Fruit" }
// Validation error request (empty name)
// POST api/products
// { "name": "", "price": 300, "category": "Fruit" }
// → 400 Bad Request
// { "errors": { "Name": ["Product name is required."] } }
// Validation error request (price is 0 or less)
// POST api/products
// { "name": "Pear", "price": 0, "category": "Fruit" }
// → 400 Bad Request
// { "errors": { "Price": ["Price must be 1 or greater."] } }
Overview
The [HttpPost] attribute is a routing attribute that binds the HTTP POST method to an action method. POST is used to create a new resource on the server or to send data to trigger some processing. Unlike GET, it can include data in the request body, making it suitable for a wide range of uses such as form submission, JSON data submission, and file upload.
For actions that create a new resource, the REST convention is to return 201 Created on success. Using CreatedAtAction() or CreatedAtRoute() automatically includes the URL of the created resource in the Location header of the response. When using [ApiController], ModelState validation errors are automatically returned as 400 Bad Request, so there is no need to manually check ModelState.IsValid inside the action method. For resource updates and deletions, refer to other HTTP method attributes such as [HttpPut], [HttpPatch], and [HttpDelete].
If you find any errors or copyright issues, please contact us.