Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should an ASP.NET Core custom InputFormatter/ReadRequestBodyAsync return to indicate error

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.

like image 615
Martin Ba Avatar asked Oct 31 '25 00:10

Martin Ba


1 Answers

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.

like image 160
Martin Ba Avatar answered Nov 02 '25 15:11

Martin Ba