diff --git a/fundamentals/middleware/problem-details-service/ProblemDetailService.csproj b/fundamentals/middleware/problem-details-service/ProblemDetailService.csproj new file mode 100644 index 00000000..f4dc5bdd --- /dev/null +++ b/fundamentals/middleware/problem-details-service/ProblemDetailService.csproj @@ -0,0 +1,15 @@ + + + + net7.0 + enable + enable + ProblemDetailsServiceSample + + + + + + + + diff --git a/fundamentals/middleware/problem-details-service/Program.cs b/fundamentals/middleware/problem-details-service/Program.cs new file mode 100644 index 00000000..c9ba79d3 --- /dev/null +++ b/fundamentals/middleware/problem-details-service/Program.cs @@ -0,0 +1,85 @@ +using Microsoft.AspNetCore.Http.Features; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Services.AddProblemDetails(options => + options.CustomizeProblemDetails = (context) => + { + var mathErrorFeature = context.HttpContext.Features.GetRequiredFeature(); + (string Detail, string Type) details = mathErrorFeature.MathError switch + { + MathErrorType.DivisionByZeroError => ("The number you inputed is zero", "https://en.wikipedia.org/wiki/Division_by_zero"), + _ => ("Negative or complex numbers are not handled", "https://en.wikipedia.org/wiki/Square_root") + }; + + context.ProblemDetails.Type = details.Type; + context.ProblemDetails.Title = "Wrong Input"; + context.ProblemDetails.Detail = details.Detail; + }); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +// middleware to handle writing problem details to the response +app.Use(async (context, next) => +{ + // added the MathErrorFeature to the request pipeline + var mathErrorFeature = new MathErrorFeature(); + context.Features.Set(mathErrorFeature); + await next(context); +}); + +app.UseStatusCodePages(); + +// endpoint for dividing numbers +app.MapGet("/divide", (HttpContext context, double numerator, double denominator) => +{ + if (denominator == 0) + { + context.Features.GetRequiredFeature().MathError = MathErrorType.DivisionByZeroError; + return Results.BadRequest(); + } + + var calculation = numerator / denominator; + return Results.Ok(calculation); +}); + +// endpoint for obtaining the squareroot of a number +app.MapGet("/squareroot", (HttpContext context, int radicand) => +{ + if (radicand < 0) + { + context.Features.GetRequiredFeature().MathError = MathErrorType.NegativeRadicandError; + return Results.BadRequest(); + } + + var calculation = Math.Sqrt(radicand); + return Results.Ok(calculation); +}); + +app.Run(); + +// Custom math errors +enum MathErrorType +{ + DivisionByZeroError, + NegativeRadicandError +} + +// Custom Http Request Feature +class MathErrorFeature +{ + public MathErrorType MathError { get; set; } +} diff --git a/fundamentals/middleware/problem-details-service/appsettings.Development.json b/fundamentals/middleware/problem-details-service/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/fundamentals/middleware/problem-details-service/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/fundamentals/middleware/problem-details-service/appsettings.json b/fundamentals/middleware/problem-details-service/appsettings.json new file mode 100644 index 00000000..10f68b8c --- /dev/null +++ b/fundamentals/middleware/problem-details-service/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}