Search code examples
c#.netrestmodel-view-controllermodel-binding

How to return only specific fields in error response using Model Binding in .NET?


I am trying to return an error response message with 200 Success status code (for some reason), but I want to return only the error message, and remove the rest of the fields generated in the response. Here is an example of the response:

{
    "title": "One or more validation errors occurred.",
    "status": 200,
    "errors": {
        "ID": [
            "ID is required"  //I want to display this only
        ]
    }
}

Only the "ID" field and its message should be returned, whereas "title", "status" and "errors" should not be returned.

Currently I've written the following code in the Startup.cs file.

     services.Configure<ApiBehaviorOptions>(o =>
            {
                o.InvalidModelStateResponseFactory = actionContext =>
                {
                    var problemDetails = new ValidationProblemDetails(actionContext.ModelState);

                    return new OkObjectResult(problemDetails);
                };
            });

Using the code below solves the problem, but instead returns 400 Bad Request status code.

            services.Configure<ApiBehaviorOptions>(o =>
            {
                o.InvalidModelStateResponseFactory = actionContext =>
                new BadRequestObjectResult(actionContext.ModelState);
            });

This is the validation attribute on the model:

[Required(ErrorMessage = "ID is required")]
public string ID { get; set; }

Solution

  • Since you're returning the whole ValidationProblemDetails object, all the properties of that will be returned.

    Since you only want errors, you can select the dictionary

    var problemDetails = new ValidationProblemDetails(actionContext.ModelState);
    var errors = problemDetails.Errors;
    
    return new OkObjectResult(errors);
    
    

    Which will return

    {
        "ID":
        [
            "ID is required"
        ]
    }
    

    If you only want the values, then select those from the dictionary instead

    var problemDetails = new ValidationProblemDetails(actionContext.ModelState);
    var errors = problemDetails.Errors;
    
    return new OkObjectResult(errors.Values);
    
    

    Which will return

    [
        "ID is required"
    ]