NOTE: In applications targeting net7.0+, Microsoft has fixed this issue, and you can set your Object to be default null (MyClass thingamagic= null), having it work as expected.
Leaving the below hack in here for anyone stuck on net6 or below.
—
You may be here because you’re getting this:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.13","title":"Unsupported Media Type","status":415,"traceId":"00-0d785f3d1cb4fd71bc36ee25561e4b48-6bc5df1f0d070024-00"}
Or this:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-8ab7d4ff2d97d5ec040c25058b8d6fff-64b7c8e21e11563b-00","errors":{"":["A non-empty request body is required."]}}
Or even this:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-2fec89d15f0fbc0a7deaf1dd96656e15-e7fabe160575f645-00","errors":{"$":["The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0."]}}
You may have tried adding this:
[FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]
And you’ve been unsuccessful in accepting queries with no Content-Type, Content-Length 0.
What you need is an attribute that will override the missing Content-Type, provide an empty JSON body for the parser, and set an appropriate Content-Length to match, and only do so when the Content-Type is missing or JSON already, so you keep the other validation.
Luckily, I’ve written one. So here you go. Leave a comment if this helps you?
[AttributeUsage(AttributeTargets.Method)]
public class AllowEmptyJsonBodyAttribute : Attribute, IResourceFilter
{
private const string StreamOverride = "StreamOverride";
public void OnResourceExecuting(ResourceExecutingContext context)
{
var request = context.HttpContext.Request;
if (!string.IsNullOrEmpty(request.ContentType) && !request.HasJsonContentType() || (request.ContentLength ?? 0) != 0) return;
request.ContentType = "application/json";
context.HttpContext.Items[StreamOverride] = request.Body; // store the original stream
var emptyPayload = Encoding.UTF8.GetBytes("{}");
request.Body = new MemoryStream(emptyPayload); // replace the stream
request.ContentLength = emptyPayload.Length;
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
if (!context.HttpContext.Items.TryGetValue(StreamOverride, out var o) || o is not Stream s) return;
var request = context.HttpContext.Request;
request.Body.Dispose(); // this disposes our injected stream
request.Body = s; // put the original back, so it can be cleaned up as usual
}
}
4 Comments
feewrew
A practical, highly targeted ASP.NET Core guide for gracefully handling missing Content Type headers and empty request bodies! Unpacking how to bypass default model binding strictness for [FromBody] parameters—through custom input formatters or global configuration tweaks provides .NET developers with the exact techniques needed to prevent unwarranted 415 Unsupported Media Type or 400 Bad Request errors and build more resilient, forgiving API endseepoints.
bbe
A practical .NET backend guide detailing how to configure ASP.NET Core APIs to gracefully accept empty JSON bodies and missing Content-Type headers! Detailing how to adjust MVC serialization options, manage model binding behavior, and prevent default validation rejections when handling non-standard client requests provides backend developers with the exact implementation blueprint needed to build resilient, flexible web services.
bbe
A practical .NET development guide detailing how to gracefully handle empty JSON bodies and missing Content-Type headers in ASP.NET Core APIs! Detailing how to customize model binding options, configure input formatters to accept empty or unformatted payloads, and bypass strict content type validation provides backend developers with the exact configuration blueprint needed to support flexible or legacy client requests without triggering bad request errors.