HTTP PUT Method in ASP.NET Core Web API

How to Implement HTTP PUT Method in ASP.NET Core Web API

In this article, I will discuss how to Implement the HTTP PUT Method in an ASP.NET Core Web API Application with Real-Time Examples. Please read our previous article about the HTTP POST Method in ASP.NET Core Web API with Examples.

HTTP PUT Method

The HTTP PUT method is a part of the Hypertext Transfer Protocol (HTTP) used to update a resource on a server. When a client wants to replace an existing resource with a new version, the PUT method is used to make the request. 

Key Characteristics of HTTP PUT Method
  • Idempotency: The PUT method is idempotency. This means multiple identical requests can be made with the same effect, i.e., not changing the outcome. 
  • Replacement: PUT is used to update or replace the current representations of the target resource with the request payload. It assumes the client is sending a complete replacement for the specified resource.
  • URLs Represent Resources: In the case of PUT requests, the URL specifies the entity being updated. If the URL refers to an existing resource, the server replaces it with the request payload. Depending on the server’s configuration, the URL might create a new resource with that URL or reject the request if the URL does not point to an existing resource.
  • Safety: It is not considered a “Safe” method because it modifies (or can modify) the server state. 
  • Payload: Clients should send a completely new version of the resource in the body of the PUT request. 
  • Response Codes: Common response codes for PUT requests include 200 (OK) if the resource is successfully updated, 201 (Created) if the PUT request results in the creation of a new resource, 204 (No Content) if the request is successful but there’s no content to return, and 404 (Not Found) if the resource does not exist and cannot be created.
How Do We Implement HTTP PUT Method in ASP.NET Core Web API?

Here’s a high-level overview of how to implement the PUT method in an ASP.NET Core Web API controller:

  • Define a Model: Start by defining a C# class representing the data model you are working with. This model will be used to accept data from the client.
  • Create a Controller: Implement a controller class derived from the ControllerBase class. This controller will contain the action method for handling PUT requests.
  • Define the PUT Action Method: Inside the controller, define an action method specifically for handling PUT requests. Use the HttpPut attribute to mark this method for handling PUT requests and specify the route if necessary.
  • Implement the Update Logic: Within the PUT action method, implement the logic to update an existing resource using the data received from the client. This often involves checking if the resource exists, updating it, and saving the changes.
  • Return a Response: The action method should return an appropriate response depending on the outcome. Common responses include OK (200) if the update was successful, NotFound (404) if the resource does not exist, and BadRequest (400) if the request data is invalid.
Defining a Model

Create a class file named Product.cs, and then copy and paste the following code:

namespace HTTPMethodDemo.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }
        public int Quantity { get; set; }
    }
}
Create a Service

Create a class file named ProductRepository.cs, and copy and paste the following code. This is the repository where we will perform all database operations related to the product model.

namespace HTTPMethodDemo.Models
{
    public class ProductRepository
    {
        public List<Product> Products = new List<Product>()
        {
            new Product() { Id = 1, Name= "Laptop", Price = 1000, Quantity = 10 },
            new Product() { Id = 2, Name= "Desktop", Price = 2000, Quantity = 20 }
        };

        public async Task<Product> UpdateProductAsync(Product product)
        {
            //Set the Product Id
            var existingProduct = Products.FirstOrDefault(u => u.Id == product.Id);

            if(existingProduct != null)
            {
                existingProduct.Price = product.Price;
                existingProduct.Quantity = product.Quantity;
                existingProduct.Name = product.Name;

                //Update the Product into the Data
            }
            
            await Task.Delay(TimeSpan.FromSeconds(1));

            return existingProduct;
        }
    }
}
Register Service:

Please add the following statement to the Program.cs class file. This will add the service to the dependency injection container.

builder.Services.AddScoped<ProductRepository>();

Creating the Controller

Create an Empty API Controller within the Controllers folder named ProductController and copy and paste the following code. This controller will contain the action method that handles PUT requests. 

using HTTPMethodDemo.Models;
using Microsoft.AspNetCore.Mvc;

namespace HTTPMethodDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private readonly ProductRepository _productRepository;

        public ProductController(ProductRepository productRepository)
        {
            _productRepository = productRepository;
        }

        // Update an Existing Product
        // PUT: api/Product/1
        [HttpPut("{id}")]
        public async Task<ActionResult<Product>> PutProduct(int id, [FromBody] Product product)
        {
            if (id != product.Id)
            {
                return BadRequest();
            }

            var result = await _productRepository.UpdateProductAsync(product);
            if(result == null)
            {
                return NotFound();
            }

            return Ok(result);
        }
    }
}
Testing the End Point:

Now, run the application and test the API endpoint, and it should work as expected:

API: Update an Existing Product

URL: https://localhost:7047/api/Product/1
Method: PUT
Request Body:

{
  "id": 1,
  "name": "Mobile",
  "price": 1500,
  "quantity": 5
}
Using Postman:

How to Implement the HTTP PUT Method in ASP.NET Core Web API with Examples

When Should We Use HTTP PUT Method in ASP.NET Core Web API?

In ASP.NET Core Web API, the HTTP PUT method is primarily used to update an existing resource on the server. Here are the specific scenarios and considerations for using the PUT method effectively:

  • Updating an Entire Resource: PUT should be used when you need to update all the fields of a resource. It replaces the entire resource with the payload provided in the request. If only a subset of data fields need to be updated, PATCH is more suitable.
  • Idempotent Operations: PUT requests are idempotent, meaning that making multiple identical requests must produce the same result as a single request. This makes PUT ideal for operations where you want to ensure a resource is updated to a specific state without side effects from multiple requests.
  • Specifying Resource Identifier: When the client is responsible for determining the identity (URI) of the resource, PUT is used. For example, updating the details of a user where the client specifies the user ID in the URI.
  • Complete Replacement: Use PUT when the operation should replace the current representation of the target resource with the request payload. If the resource does not exist, PUT may also be used to create a new resource, depending on the API design, although POST is more commonly used for creation.
When Not to Use HTTP PUT Method in ASP.NET Core Web API:

The HTTP PUT method in ASP.NET Core Web API is primarily used for updating an existing resource or creating a resource at a specific URL if it doesn’t exist. However, there are several scenarios where using the PUT method might not be the best choice:

  • Partial Updates: PUT is designed to replace the entire resource with the payload provided in the request. If your intention is to update only a part of the resource, PATCH is a more appropriate method, as it allows for partial modification without affecting the untouched parts.
  • Non-idempotent Operations: While PUT requests are idempotent, meaning multiple identical requests should have the same effect as a single request, this behavior might not be desired in all cases. POST might be more appropriate if your operation needs to perform non-idempotent actions (where subsequent identical requests can have different effects).
  • Lack of a Clear URI: PUT requests are supposed to be made to a specific resource URI. If your application logic does not have a clear URI for the resource being created or updated, or if the resource identification is managed internally rather than through the URI, POST might be a better method as it does not require the client to know the URI of the resource beforehand.
  • Overwriting Unintentionally: Since PUT replaces the entire resource, there’s a risk of unintentionally overwriting data if the client’s representation of the resource is incomplete or outdated. Careful consideration is needed to avoid data loss, especially in environments where concurrent modifications to resources are common.
  • Complex Validation Logic: POST might offer more flexibility if the update operation involves complex validation logic or needs to trigger additional side effects beyond just the resource update. PUT is best used for straightforward replacement operations.

HTTP Post vs. PUT Method in ASP.NET Core Web API

In ASP.NET Core Web API, HTTP POST and PUT methods transmit data from a client to a server, but they serve different purposes. Understanding the distinction between these two methods is crucial for implementing RESTful APIs that adhere to HTTP principles and standards.

HTTP POST Method
  • Purpose: The POST method creates a new resource on the server. When you send a POST request, you ask the server to accept and store the data provided in the body of the request. It’s commonly used for submitting form data or uploading a file.
  • Idempotency: POST requests are not idempotent, which means that making multiple identical POST requests will likely result in different outcomes each time. For example, sending the same POST request multiple times could create multiple resources or entries in a database.
  • Server Control over Resource ID: With POST, the server controls the created resource ID. The client does not know the ID until the server responds.
  • Response Codes: A successful POST request might return HTTP status codes like 201 (Created) if a new resource was successfully created or 202 (Accepted) if the request has been accepted for processing but the processing has not been completed.
  • Payload: POST requests often carry data meant to be stored or processed by the server, potentially resulting in a new resource that doesn’t necessarily have a direct relationship to the request URI.
  • Use Cases: It’s typically used to create new entities within a collection, such as a new user in a user database or submitting data from a form.
HTTP PUT Method
  • Purpose: The PUT method updates an existing resource or creates a new resource if it does not exist at the specified URI. A PUT request replaces all current representations of the target resource with the request payload.
  • Idempotency: PUT requests are idempotent, meaning repeating the same PUT request multiple times will always produce the same result. This is because the PUT method replaces the entire entity at the specified URI with the one contained in the request.
  • Server Control over Resource ID: With PUT, the client specifies the resource ID in the URL, effectively having control over the resource’s location on the server.
  • Response Codes: A successful PUT request might return a 200 (OK) or 204 (No Content) if an existing resource is successfully modified or a 201 (Created) if a new resource was made.
  • Payload: PUT requests completely represent the resource to be updated or created. If updating, the client sends the full updated entity, not just the changes.
  • Use Cases: It’s commonly used to update existing entities within a collection, such as a user’s profile information. PUT requests are also used when the client determines the URI of the new resource rather than the server.
Choosing Between POST and PUT
  • Use POST when you want to create a new instance of a resource and you do not have a URI for the new resource. The server will decide on the URI and return it in response.
  • Use PUT when you want to update an existing resource or create a new resource at a specific URI that you know.

In the next article, I will discuss how to Implement the HTTP PATCH Method in an ASP.NET Core Web API Application with Examples. In this article, I explain how to Implement the HTTP PUT Method in the ASP.NET Core Web API Application with Examples. I hope you enjoy this article, “How to Implement HTTP PUT Method in ASP.NET Core Web API.”

Leave a Reply

Your email address will not be published. Required fields are marked *