I think this change is due to .NET Core - where ASP.NET tries to do everything out of the box, ASP.NET Core only does what you specifically tell it to (which is a big part of why it's so much quicker and portable).
If you want this behaviour in Core you need to add it, either as a package that someone has written for you or by rolling your own.
It's fairly simple. First you need a custom exception to check for:
public class StatusCodeException : Exception
{
public StatusCodeException(HttpStatusCode statusCode)
{
StatusCode = statusCode;
}
public HttpStatusCode StatusCode { get; set; }
}
Then you need a RequestDelegate
handler that checks for the new exception and converts it to the HTTP response status code:
public class StatusCodeExceptionHandler
{
private readonly RequestDelegate request;
public StatusCodeExceptionHandler(RequestDelegate next)
{
this.request = next;
}
public Task Invoke(HttpContext context) => this.InvokeAsync(context); // Stops VS from nagging about async method without ...Async suffix.
async Task InvokeAsync(HttpContext context)
{
try
{
await this.request(context);
}
catch (StatusCodeException exception)
{
context.Response.StatusCode = (int)exception.StatusCode;
context.Response.Headers.Clear();
}
}
}
Then you register this middleware in your startup:
public class Startup
{
...
public void Configure(IApplicationBuilder app)
{
...
app.UseMiddleware<StatusCodeExceptionHandler>();
Finally you can throw the HTTP status code exception in your actions, while still returning an explicit type that you can easily unit test:
public Thing Get(int id) {
Thing thing = GetThingFromDB();
if (thing == null)
throw new StatusCodeException(HttpStatusCode.NotFound);
return thing;
}
This is fairly simple and someone out there has probably written a more complete one, but I haven't been able to find one or get a clear answer as to why this was dropped.