Home > Software engineering >  Is it possible to hide C# implementation details from a 400 Asp.Net Core response?
Is it possible to hide C# implementation details from a 400 Asp.Net Core response?

Time:11-18

When I get an automated 400 from Asp.Net Core, there are often some implementation details that I do not want to expose, nor are they relevant really, e.g.:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-71b3ed06990f759c440ed484475b437c-23db588b254e8013-00",
    "errors": {
        "$": [
            "JSON deserialization for type 'MyExampleNamespace.MyRequest' was missing required properties, including the following: messageId"
        ],
        "request": [
            "The request field is required."
        ]
    }
}
public record MyRequest
{
   public required MessageId { get; init; }
}

Example request: json

{
   "notMessageId": "hello"
}

So what I expect to get is a more "non C# dependent response" that does not include fully qualified C# names in response.

CodePudding user response:

Do a custom implementation for errors:

public class ErrorHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public ErrorHandlerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
    {
        _next = next;
        _logger = loggerFactory.CreateLogger<ErrorHandlerMiddleware>();
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception error)
        {

            var problemDetails = new ProblemDetails
            {
                Title = "An unexpected error occurred!",
                Detail = error.GetType().Name,
                Status = StatusCodes.Status400BadRequest,
                Extensions =
                {
                    ["trace"] = Activity.Current?.Id ?? context?.TraceIdentifier
                }
            };


            context.Response.ContentType = "application/problem json";
            context.Response.StatusCode = problemDetails.Status.Value;
            context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
            {
                NoCache = true,
            };
            await JsonSerializer.SerializeAsync(context.Response.Body, problemDetails);
        } 
    } 
}

I would use inside the catch a switch case based on error type and redefine the error message output.

Use it like this: app.UseMiddleware<ErrorHandlerMiddleware>();.

CodePudding user response:

Turn off UseDeveloperExceptionPage. With this, you will see the detailed exceptions only in the dev environment. In production you will see whatever you define in the Error page

if (env.IsDevelopment())  
{  
     app.UseDeveloperExceptionPage();  
}  
else  
{  
     app.UseExceptionHandler("/Error");  
}  
  • Related