Skip to main content

Handling Null Response using NullResponseMiddleware in .Net Core

Whenever we get empty response from database or internal API call, we should return a structured, meaningful response should return to the client, even when no data is available.

Let’s understand problem

Consider below code.

[ApiController]
[Route("[controller]")]
public class NullResponseController : ControllerBase
{

private readonly ILogger<NullResponseController> _logger;

private readonly Dictionary<int, string> _usersDetails = new Dictionary<int, string>
{
{ 1, "Devesh omar" },
{ 2, "Ram Kumar" }
};
public IActionResult GetUser(int id)
{
if (_usersDetails.TryGetValue(id, out var user))
{
return Ok(user); // Return user details
}

// Returns null response
return Ok();

}
public NullResponseController(ILogger<NullResponseController> logger)
{
_logger = logger;
}


}

a. Unintentional Mistakes:

In this code (GetUser API)we are sending blank or empty data to client when data not found in database. These code cause confusion to UI developer, and he will never understand if there are some problem in API side or he is getting blank data accidently.

Let’s Execute below code or endpoint and see what response we get if we send empty or just return ok();

When we executed below endpoint, we can see we are getting blank response and response body is blank.

b. Client-Side issues.

Many clients (e.g., JavaScript-based apps) do not handle null or empty responses gracefully, potentially leading to runtime errors like:

Cannot read property of null

Example: A client expecting a JSON object receives an empty response and crashes because JSON.parse() fails.

c. Unexpected HTTP Status Codes

if api those returning empty response and still sending HTTP status 200 , that can mislead clients into thinking the request was successful when there was no data to process.

In such cases we should respond with proper status codes like 204 No Content should

Solution: Custom NullResponseMiddleWare

To handle above scenario we can create NullResponseMiddleware which will see if response is null then it will send default message to client

Let’s create custom Middleware

public class NullResponseHandlingMiddleware
{
private readonly RequestDelegate _next;

public NullResponseHandlingMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task InvokeAsync(HttpContext context)
{
// Create a memory stream to intercept the response
using var memoryStream = new MemoryStream();
var originalBodyStream = context.Response.Body;
context.Response.Body = memoryStream;

// Proceed with the pipeline
await _next(context);

// Reset the stream position to read the response
memoryStream.Seek(0, SeekOrigin.Begin);
var responseBody = await new StreamReader(memoryStream).ReadToEndAsync();

// If the response body is empty, replace it
if (string.IsNullOrWhiteSpace(responseBody) && context.Response.StatusCode == 200 || context.Response.StatusCode == 204)
{
context.Response.Body = originalBodyStream; // Reset the original stream
context.Response.ContentType = "application/json";
await context.Response.WriteAsync("{\"message\": \"No content available for this API.\"}");
}
else
{
// Copy the original response body back to the stream
memoryStream.Seek(0, SeekOrigin.Begin);
await memoryStream.CopyToAsync(originalBodyStream);
}
}
}

Implementation details

a. We are creating custom middleware with name NullResponseHandlingMiddleware

b. Inside Invoke Method we will read response body and will see if response if blank or null , if response if blank then we will send Default message (line number 32 in below code), else respond with original data.

Register middleware at startup.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseMiddleware<NullResponseHandlingMiddleware>();

Code execution

After code execution we can see if we are sending blank data then we will be getting default message.

This Solution work well in scenario when we have 1000’s of API in application and we want to fix all end point in applications with this centralize solution.

Thanks.

Happy Coding and Happy learning


Comments

Popular posts from this blog

Design Application using Clean Architecture

  Clean Architecture , introduced by  Robert C. Martin   (Uncle Bob), aims to create systems that are: Independent of frameworks Testable Independent of UI Independent of database Independent of any external agency Clean Architecture emphasizes separating the concerns of different parts of the system and ensuring that each part has a clear responsibility. .NET clean architecture as a development approach, available in a layered form to reduce dependency. The architecture consists of several layers, each with a specific role and dependencies that flow in one direction: from the outer layers to the inner layers. Inner most Layer is independent to its outer layer, means inner most layer does not have any references, it builds and stand independently. Dependency Rule The core principle of Clean Architecture is the  Dependency Rule , which states that source code dependencies can only point inward.  This means: Nothing in inner circle can depend on anything in an out...

How to Earn online from Medium.com

  As freelancer I started writing on medium (Tech blogs) from  Aug 2024   but I was already writing tech blogs on c-sharpcorner.com “The purpose of this post is to encourage new writers by helping them understand how they can earn as freelancers.” “Medium is a great platform for writers. When I started writing, I had no idea that I would reach the $100 benchmark in just four months. Now, I’m feeling self-inspired, as it has become a valuable source of income as a freelancer.” AUG 2024 ( $0 ) It was just beginning, and I posted 4 articles and had only few views 455 and 165 reads. During this time, I was learning about medium rules for writers and partner program. It will take some time to understand over all process. SEP 2024 ($6) As I started writing and I was getting few cents on Aug 2024, I posted 8 more articles in SEP, and it was good month because my blogs were getting noticed and I started getting claps etc. “This month, I went from $0 to $6, which was an achievemen...

Fixing High CPU Usage in .NET Core using Parallelism

  We will fix problem occurs due to incorrect use Parallelism in .NET Core To increase application performance sometimes we use process task or work extensively in Parallel and that may lead performance issue. When we do code, we should understand our requirement very carefully along with hardware resources those we have. We should code like that there should be less CPU usage and server should work without issues. In .NET Core, when you’re using parallelism (like Parallel.For, Task.WhenAll, or Task.Run), you might encounter performance issues if the number of concurrent threads or tasks exceeds what your system can efficiently handle. A common issue is high CPU usage or resource contention, which can degrade overall performance, cause excessive context switching, and even lead to thread starvation or deadlocks. Non members can access from here Effective Parallelism Strategies to Mitigate High CPU Usage in .NET Core We will fix problem occurs due to incorrect use Parallelism in .NE...