Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
89 views
in Technique[技术] by (71.8m points)

c# - Handling ASP.NET Core Web API object property binding

I have an ASP.NET Core 2.1 Web API application. If I send to API endpoint empty quotes as json object property value in request body I`ll have that property been initialized with null (it is of type Guid?). How can I change such behavior? What I need is just send BadRequest (400) as response error code.

That is an endpoint:

public async Task<ActionResult<ExampleResponse>> ExamplePatch([FromBody] ExampleModel exampleModel,
        CancellationToken cancellationToken)
{
    /* At this point exampleModel.ExampleGuid is initilized with null. So it should be handled before */
    /* some processing */
    return StatusCode(StatusCodes.Status201Created, ExampleResponse);
}

Here is the model:

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.10.53.0 (Newtonsoft.Json v9.0.0.0)")]
public class ExampleModel 
{
    /* a bunch of properties here */
    [Newtonsoft.Json.JsonProperty("exampleGuid", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
    public System.Guid? ExampleGuid { get; set; }
}

Json from request body:

{ ... other parameters here ..., "exampleGuid": "" }

I have one restriction on that - I cannot add attributes to that model property or change the model somehow. I`ll be very appreciated for any help!

question from:https://stackoverflow.com/questions/66051248/handling-asp-net-core-web-api-object-property-binding

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can create a Validator for the ExampleModel with FluentValidation package. Here is the example:

public class ExampleModelValidator : AbstractValidator<ExampleModel>
    {
        public ExampleModelValidator()
        {
            RuleFor(e => e.ExampleGuid)
                .Must(guid => guid.ToString().lenght > 0)
                 .When(e => e.ExampleGuid.HasValue)
                 .WithMessage("Must be a valid GUID");

        }
    }

This will validate your model before the endpoint body.

Additionaly I personally like to add this piece of code in my Startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        services
            
            .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<ExampleModelValidator>())
            .ConfigureApiBehaviorOptions(options =>
            {
                options.InvalidModelStateResponseFactory = context =>
                {
                    var errorsList = string.Join(" | ", context.ModelState.Values.SelectMany(v => v.Errors).Select(err => err.ErrorMessage).ToArray());
                    return new BadRequestObjectResult(errorsList);
                };
            });
    }

This will return all validation messages separated by pipe and BadRequest as response.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...