I'm attempting to test request timeout functionality in a C# ASP.NET Core 8 Web API on my local environment.
Here's my setup: in Program.cs
, I've configured middleware using AddRequestTimeouts
and UseRequestTimeouts
. I've defined a default policy and an additional policy named ThreeSecondsPolicy
. I've set Timeout
, TimeoutStatusCode
, and WriteTimeoutResponse
properties for both policies.
Here's a snippet of the relevant code from Program.cs
:
builder.Services.AddRequestTimeouts(options => { options.DefaultPolicy = new RequestTimeoutPolicy { Timeout = TimeSpan.FromMilliseconds(100), TimeoutStatusCode = (int)HttpStatusCode.RequestTimeout, WriteTimeoutResponse = async (HttpContext context) => { context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Timeout from Default Policy!"); } }; options.AddPolicy("ThreeSecondsPolicy", new RequestTimeoutPolicy { Timeout = TimeSpan.FromMilliseconds(3000), TimeoutStatusCode = (int)HttpStatusCode.RequestTimeout, WriteTimeoutResponse = async (HttpContext context) => { context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Timeout from ThreeSecondsPolicy!"); } }); }); app.UseRequestTimeouts();
In my controller method, annotated with [RequestTimeout(policyName: "ThreeSecondsPolicy")]
Here's a snippet of the controller and service method:
[Route("/details")] [HttpGet] [RequestTimeout(policyName: "ThreeSecondsPolicy")] public async Task<ActionResult<StudentResponse>> GetstudentDetails([Required, FromQuery] string studentId) { try { StudentResponse StudentResponse = await factory.Service.ExecuteStudentDetails(studentId, HttpContext.RequestAborted); if (StudentResponse != null && StudentResponse.studentDetails != null) { if (StudentResponse.studentDetails.Any()) { StudentResponse.ActionResult = new StudentDetailsActionResult { Code = HttpStatusCode.OK, Messages = new List<string> { "Success" } }; return Ok(StudentResponse); } else { LogException(HttpStatusCode.OK, new List<string> { "Empty result" }); StudentResponse = new StudentResponse { ActionResult = new StudentDetailsActionResult { Code = HttpStatusCode.OK, Messages = new List<string> { "Empty result" } } }; return StatusCode(200, StudentResponse); } } } catch (Exception ex) { LogException(HttpStatusCode.InternalServerError, new List<string> { ex.ToString() }); return StatusCode(500, ex.Message); } } public async Task<StudentResponse> ExecuteStudentDetails( string id, CancellationToken token) { token.ThrowIfCancellationRequested(); try { var studentData = await dataAccessHelper.GetStudentData(id); StudentResponseMapper studentResponseMapper = factory.CreateStudentResMapper(); var data = studentResponseMapper.MapResponse(studentData); return data; } catch (OperationCanceledException) { // Return a custom response indicating a request timeout (408 status code with a custom message) var timeoutResponse = new StudentResponse { // You can customize the response message as needed ActionResult = new StudentDetailsActionResult { Code = HttpStatusCode.RequestTimeout, Messages = new List<string> { "Request timed out" } } }; return timeoutResponse; } }
I'm running the application without the debugger attached, as recommended by Microsoft's documentation.
While testing, I'm observing the following:
- Timeout functionality is working as expected in Postman.
- However, I'm not receiving the expected status code 408 or the custom message set in
WriteTimeoutResponse
property inProgram.cs
.
How can I resolve these issues and accurately get status code with custom message?
Any insights or suggestions would be greatly appreciated. Thank you!