TL;DR
If my Content-Type "application/x-ourformat"
bound custom TextInputFormatter
cannot parse the input, I want to return HTTP 400
(possibly 415
) back to the client.
What is the correct way to return from the implementation of ReadRequestBodyAsync
to get the framework to return a 4xx
HTTP response?
We have a custom formatter for application/x-ourformat
built upon the TextInputFormatter
as explained in the link.
The example from the MS docs above does error handling as follows:
public override async Task<InputFormatterResult> ReadRequestBodyAsync(
InputFormatterContext context, Encoding effectiveEncoding)
{
...
return await InputFormatterResult.SuccessAsync(contact);
}
catch
{
logger.LogError("Read failed: nameLine = {nameLine}", nameLine);
return await InputFormatterResult.FailureAsync();
}
}
That is, if the processing of the input fails with an exception, it will return FailureAsync()
.
However, this will NOT result in a HTTP 400 response, instead the input object bound to the Api will simply be null
.
What does result in a 400 response is:
- Throwing an exception out of
ReadRequestBodyAsync
- Setting
context.ModelState.AddModelError("My Key", "Couldn't really understand you.");
prior to returningFailureAsync
.
But I do neither understand which one is "correct" nor do I really understand what the ModelError is supposed to represent.
CodePudding user response:
I have now dug into the call chain for ReadRequestBodyAsync
:
Eventually the result will be processed in BindModelAsync
, which:
- On HasError, Logs, and returns nothing, stating
// Formatter encountered an error. Do not use the model it returned.
- On exception, does
ModelState.AddModelError(modelBindingKey, exception
So, since the framework itself will set a ModelError on an exception, it sure seems at least that setting the ModelError oneself is more useful.
Like ckuri noted above :
A model error represents that the model ... doesn’t satisfy a constraint or contains malformed data. Therefore, it kinda applies in your case.
CodePudding user response:
Below is a sample response. Notice the 200 OK is before the http headers. The HTTP headers have a key and a value separated by a colon. The body is after the headers. the content length is the number of bytes in the body.
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
Hello World! My content includes a trailing CRLF.