Home > Back-end >  How should an ASP.NET Core custom InputFormatter/ReadRequestBodyAsync return to indicate error
How should an ASP.NET Core custom InputFormatter/ReadRequestBodyAsync return to indicate error

Time:11-12

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:

ReadRequestBodyAsync:

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 returning FailureAsync.

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.
  • Related