aspnet / Announcements

Subscribe to this repo to be notified about major changes in ASP.NET Core and Entity Framework Core

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Breaking change]: ActionResult<T> set StatusCode to 200

brunolins16 opened this issue · comments

Description

When returning a T in a MVC/API Controller Action that declares the return type as ActionResult<T> will now always set the ObjectResult.StatusCode to 200, unless when the T is a ProblemDetails.

Since before this change the ObjectResult.StatusCode was null, in some scenarios where the status code is set manually, this change could cause unexpected behaviors. Also, an Action Filter could be affected by this change if it expects the null instead of 200.

Version

.NET 6

Previous behavior

Before if you have a Controller's Action that returns T and sets the Response.StatusCode manually, similar to the example:

// Generates a 202 Accepted response
public ActionResult<Model> Get()
{
    Response.StatusCode = StatusCodes.Status202Accepted;
    return new Model();
}

It will generate the expected 202 Accepted response status code.

New behavior

After the changes the same Controller's Action that returns T that sets the Response.StatusCode manually, will always generate a 200 OK response.

// Generates a 200 OK response
public ActionResult<Model> Get()
{
    Response.StatusCode = StatusCodes.Status202Accepted;
    return new Model();
}

Type of breaking change

  • Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load/execute or different run-time behavior.
  • Source incompatible: Source code may encounter a breaking change in behavior when targeting the new runtime/component/SDK, such as compile errors or different run-time behavior.

Reason for change

This behavior is documented since ASP.NET Core 3.1 (https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-3.1#actionresultt-type), however, it keeps the StatusCode as null that will eventually generate a 200 OK response as default. Since the default internal behavior could easily change, was decided to avoid relying on the internal default implementation and setting the StatusCode to the expected 200 OK.

Recommended action

If you are broken by this change, as the example mentioned before:

public ActionResult<Model> Get()
{
    Response.StatusCode = StatusCodes.Status202Accepted;
    return new Model();
}

You will need to change your Controller Action. These are some possible options that will keep the desired behavior:

public ActionResult<Model> Get()
{
   return Accepted(new Model());
}

//or

public ActionResult<Model> Get()
{
   return StatusCode(StatusCodes.Status202Accepted, new Model());
}

//or

public Model Get()
{
   Response.StatusCode = StatusCodes.Status202Accepted;
   return new Model();
}

Affected APIs

MVC/API Controller actions.