How I can adjust which fields I will have in the response of a model validation (.NET Core Web Api)?

Cenk 991 Reputation points
2023-07-26T05:54:19.46+00:00

Hi,

I have the following response when there is a validation error;

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-ea3f1a67ca3f19d5095b9b671e7b5bff-22418dfbef019280-00",
    "errors": {
        "price": [
            "Price is required for this product code."
        ],
        "quantity": [
            "The quantity must be added.(quantity = 1)"
        ]
    }
}


Actually, I don't need type, title and traceId. How to remove for each response the fields: type, title and traceId. Is there a simple way?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,400 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Chathura Munasinghe 170 Reputation points
    2023-07-26T07:41:28.8333333+00:00

    In .NET Core Web API, you can customize the response for model validation errors by implementing a custom ValidationProblemDetails class and overriding the OnSerialize method. This allows you to remove specific fields like "type," "title," and "traceId" from the response.

    Here's how you can achieve this:

    1. Create a custom ValidationProblemDetails class that inherits from the built-in ValidationProblemDetails class:
    using Microsoft.AspNetCore.Mvc;
    
    public class CustomValidationProblemDetails : ValidationProblemDetails
    {
        // Override the OnSerialize method to remove unwanted fields
        public override void OnSerialize(Microsoft.AspNetCore.Http.Json.JsonElementWriter writer)
        {
            // Remove the "type," "title," and "traceId" fields from the response
            writer.WriteStartObject();
            writer.WriteEndObject();
        }
    }
    
    
    

    In your controller, when you want to return a model validation error, use the CustomValidationProblemDetails class:

    [ApiController]
    public class YourController : ControllerBase
    {
        [HttpPost]
        public IActionResult SomeAction([FromBody] YourModel model)
        {
            if (!ModelState.IsValid)
            {
                // Create a new instance of the custom validation problem details
                var problemDetails = new CustomValidationProblemDetails
                {
                    Status = 400,
                    Title = "One or more validation errors occurred.",
                    // Populate the errors dictionary based on your model's validation errors
                    Errors = ModelState.ToDictionary(
                        kvp => kvp.Key,
                        kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
                    )
                };
    
                // Return the custom validation problem details
                return new BadRequestObjectResult(problemDetails);
            }
    
            // Your regular code here for successful processing
            return Ok();
        }
    }
    
    
    

    In this example, we've created a custom class CustomValidationProblemDetails that inherits from ValidationProblemDetails and overrides the OnSerialize method to remove the unwanted fields from the response. Then, in the controller, we use this custom class to create and return the response for model validation errors.

    By using this approach, you can control the fields included in the response for model validation errors and remove the "type," "title," and "traceId" fields as you desired.

    1 person found this answer helpful.

  2. Ruikai Feng - MSFT 2,556 Reputation points Microsoft Vendor
    2023-07-26T08:57:02.4366667+00:00

    Hi,@Cenk

    I suggest not to to replace the default bad request response,you could check the document related

    The ValidationProblemDetails type:

    • Provides a machine-readable format for specifying errors in web API responses.
    • Complies with the RFC 7807 specification.

    If you insist on replacing the default response,

    public class ValidationProblemDetailsResult : IActionResult
        {
            public async Task ExecuteResultAsync(ActionContext context)
            {
                var keys = context.ModelState.Keys;
                var dic = context.ModelState.ToDictionary(
                        kvp => kvp.Key,
                        kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
                    );
                var problemDetails = new 
                {
                    Status = StatusCodes.Status400BadRequest,                
                    Errors= dic
                };
                var objectResult = new ObjectResult(problemDetails) { StatusCode = problemDetails.Status };
                await objectResult.ExecuteResultAsync(context);
            }
        }
    

    configure here in Program.cs:

    builder.Services
        .Configure<ApiBehaviorOptions>(x => x.InvalidModelStateResponseFactory = ctx => new ValidationProblemDetailsResult());
    
    
    

    Rsult:

    User's image


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Ruikai Feng