0

When we have an action, accepting the following argument:

[FromBody][Range(1, 10)] int hello

When validation fails, the object returned has an empty entry, like so:

"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|3b00401-417ccac45f29647d.",
"errors": {
    "": [
        "hello is required."
    ]
}

}

Why is that? Could you refer to the source which is causing this problem? I believe it's tied with reflection, i.e they get the object's properties, but in our case it's a simple int/string object, not a custom type.

SpiritBob
  • 2,355
  • 3
  • 24
  • 62

2 Answers2

0

Firstly,you can refer to this

and you can see the default BadRequest response:

errors": {
    "": [
      "A non-empty request body is required."
    ]

It should be "number": [ "The field number...." but right now it's "" : [ "The field number...,so the response is a default response format. And if you want to custom errors,you can do like this:

public class CustomBadRequest : ValidationProblemDetails
    {
        public CustomBadRequest(ActionContext context)
        {
            Title = "Invalid arguments to the API";
            Detail = "The inputs supplied to the API are invalid";
            Status = 400;
            ConstructErrorMessages(context);
            Type = context.HttpContext.TraceIdentifier;
        }

        private void ConstructErrorMessages(ActionContext context)
        {
            var reader = new StreamReader(context.HttpContext.Request.Body);
            var body = reader.ReadToEndAsync();
            

            
            foreach (var keyModelStatePair in context.ModelState)
            {
                var key = keyModelStatePair.Key;
                if (key == "")
                {
                    Errors.Add("number", new string[] { "nmber is not between 1,10" });
                }
                else
                {
                    Errors.Add("number", new string[] { "this is not number" });
                }
           }
        }

        string GetErrorMessage(ModelError error)
        {
            return string.IsNullOrEmpty(error.ErrorMessage) ?
                "The input was not valid." :
            error.ErrorMessage;
        }
}

Modify in Startup.cs

services.AddControllersWithViews()
                .ConfigureApiBehaviorOptions(options=>
                {
                    options.InvalidModelStateResponseFactory = contet =>
                    {
                        var problems = new CustomBadRequest(contet);
                        return new BadRequestObjectResult(problems);
                    };
                });

result: enter image description here enter image description here

Yiyi You
  • 16,875
  • 1
  • 10
  • 22
  • This is not the case for when we use `[FromBody][Range(1, 10)] int number`. You get an empty entry. Why? – SpiritBob Sep 03 '20 at 07:00
  • I have updated my answer,you need to check your data format,it need to be json type, in ajax you can use `JSON.stringify(xxx)` – Yiyi You Sep 03 '20 at 08:16
  • Yes, but you don't answer my question: Why do we get an empty string entry for the error? How do we fix it? It should be `"number": [ "The field number....`" but right now it's `"" : [ "The field number...` – SpiritBob Sep 03 '20 at 10:30
  • I have updated my answer,"":["xxxx"] is a default format. – Yiyi You Sep 04 '20 at 07:28
  • This also does not answer my question. You are changing the default 400 error returned from the API, where I simply wish to re-name "" in that specific case to something else... – SpiritBob Sep 04 '20 at 10:57
0

You can achieve this by using the ModelBinder attribute.

For example:

[ModelBinder(Name = "number")]

SpiritBob
  • 2,355
  • 3
  • 24
  • 62