How to return a specific status code and no contents from Controller?
this.HttpContext.Response.StatusCode = 418; // I'm a teapot
How to end the request?
Try other solution, just:
return StatusCode(418);
You could use StatusCode(???)
to return any HTTP status code.
Also, you can use dedicated results:
Success:
return Ok()
← Http status code 200return Created()
← Http status code 201return NoContent();
← Http status code 204
Client Error:
return BadRequest();
← Http status code 400return Unauthorized();
← Http status code 401return NotFound();
← Http status code 404
More details:
- ControllerBase Class (Thanks @Technetium)
- StatusCodes.cs (consts aviable in ASP.NET Core)
- HTTP Status Codes on Wiki
- HTTP Status Codes IANA
How to return a custom HTTP status/message in ASP.NET Core without returning object, IActionResult, etc?
references:
ASP.NET Core APIs in the fast lane with Swagger and Autorest
Adding swagger in ASP.NET Core Web API
ASP.NET Core 1.0 MVC API documentation using Swashbuckle Swagger
For output definition, just add the
[Produces]
and[SwaggerResponse]
attributes describing the Type
returned, like this:
[HttpGet]
[Produces(typeof(Employee))]
[SwaggerResponse(System.Net.HttpStatusCode.OK, Type = typeof(Employee))]
public async Task<IActionResult> LoadEmployee(string id) {
var employee = await repository.GetById(id);
if(employee == null) {
return NotFound();
}
return Ok(employee);
}
.Net Web API return statuscode with specific type without actionresult?
I post an answer here in case anyone needs something similar.
So I ended up creating a custom ActionFilter that does the job although I hoped for something a bit more elegant.
public class StatusCodeAttribute : ProducesResponseTypeAttribute, IActionFilter
{
private readonly int statusCode;
public StatusCodeAttribute(HttpStatusCode statusCode)
:base((int)statusCode)
{
this.statusCode = (int)statusCode;
}
public void OnActionExecuted(ActionExecutedContext context)
{
context.HttpContext.Response.StatusCode = this.statusCode;
}
public void OnActionExecuting(ActionExecutingContext context)
{
// not going to use this
return;
}
}
Implementing the IActionFilter
interface gives you access to the context
of an action call, and through it, the HttpContext
itself, so you can set the status code manually (yeah, it was a wrong assumption that any means of redirection is needed). I used the HttpStatusCode
enum to safeguard against using arbitrary codes.
The implementation also uses the ProducesResponseTypeAttribute
to indicate the response status code to code editors. Since we do not use generic return types, the exact types are picked up by swagger. The only downside of this implementation is that the Content-Type is not. Below image testifies that swagger indeed picked up the data on my EventController, but it did not know about the Contet-Type.
Even though there is room for improvement, this is basically what I needed. If anybody knows any downsides to my implementation, please do not hesitate to comment, although I do not think that setting the status code this way would be harmful in any way nor would it be a performance hindrance.
EDIT
I forgot to mention that I changed the base class of the Controller from ControllerBase
to Controller
, because this implementation has the filter features I used in the code.
How to return a status code from an endpoint that can then be handled by app.UseStatusCodePages() middleware?
The issue was that I have the ApiController
attribute on the endpoint controller. One of the things this attribute does is to automatically create a ProblemDetails
response body for any failed requests, and it is this that prevents UseStatusCodePages
from having any effect.
The solution is to either remove the ApiController
attribute if you do not require any of its features, or alternatively its behaviour of automatically creating ProblemDetails
responses can be disabled using the following configuration in Program.cs
(or Startup.cs
in old style projects).
builder.Services.AddControllers().ConfigureApiBehaviorOptions(options =>
{
options.SuppressMapClientErrors = true;
});
How to return both custom HTTP status code and content?
You can use ContentResult
:
return new ContentResult() { Content = myContent, StatusCode = myCode };
How to return a 200 HTTP Status Code from ASP.NET MVC 3 controller
In your controller you'd return an HttpStatusCodeResult like this...
[HttpPost]
public ActionResult SomeMethod(...your method parameters go here...)
{
// todo: put your processing code here
//If not using MVC5
return new HttpStatusCodeResult(200);
//If using MVC5
return new HttpStatusCodeResult(HttpStatusCode.OK); // OK = 200
}
Returning http status code from Web Api controller
I did not know the answer so asked the ASP.NET team here.
So the trick is to change the signature to HttpResponseMessage
and use Request.CreateResponse
.
[ResponseType(typeof(User))]
public HttpResponseMessage GetUser(HttpRequestMessage request, int userId, DateTime lastModifiedAtClient)
{
var user = new DataEntities().Users.First(p => p.Id == userId);
if (user.LastModified <= lastModifiedAtClient)
{
return new HttpResponseMessage(HttpStatusCode.NotModified);
}
return request.CreateResponse(HttpStatusCode.OK, user);
}
ASP.NET Core return JSON with status code
The most basic version responding with a JsonResult
is:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
However, this isn't going to help with your issue because you can't explicitly deal with your own response code.
The way to get control over the status results, is you need to return a
ActionResult
which is where you can then take advantage of theStatusCodeResult
type.
for example:
// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authorRepository.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
Note both of these above examples came from a great guide available from Microsoft Documentation: Formatting Response Data
Extra Stuff
The issue I come across quite often is that I wanted more granular control over my WebAPI rather than just go with the defaults configuration from the "New Project" template in VS.
Let's make sure you have some of the basics down...
Step 1: Configure your Service
In order to get your ASP.NET Core WebAPI to respond with a JSON Serialized Object along full control of the status code, you should start off by making sure that you have included the AddMvc()
service in your ConfigureServices
method usually found in Startup.cs
.
It's important to note that
AddMvc()
will automatically include the Input/Output Formatter for JSON along with responding to other request types.
If your project requires full control and you want to strictly define your services, such as how your WebAPI will behave to various request types including application/json
and not respond to other request types (such as a standard browser request), you can define it manually with the following code:
public void ConfigureServices(IServiceCollection services)
{
// Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
// https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs
services
.AddMvcCore(options =>
{
options.RequireHttpsPermanent = true; // does not affect api requests
options.RespectBrowserAcceptHeader = true; // false by default
//options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
//remove these two below, but added so you know where to place them...
options.OutputFormatters.Add(new YourCustomOutputFormatter());
options.InputFormatters.Add(new YourCustomInputFormatter());
})
//.AddApiExplorer()
//.AddAuthorization()
.AddFormatterMappings()
//.AddCacheTagHelper()
//.AddDataAnnotations()
//.AddCors()
.AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}
You will notice that I have also included a way for you to add your own custom Input/Output formatters, in the event you may want to respond to another serialization format (protobuf, thrift, etc).
The chunk of code above is mostly a duplicate of the AddMvc()
method. However, we are implementing each "default" service on our own by defining each and every service instead of going with the pre-shipped one with the template. I have added the repository link in the code block, or you can check out AddMvc()
from the GitHub repository..
Note that there are some guides that will try to solve this by "undoing" the defaults, rather than just not implementing it in the first place... If you factor in that we're now working with Open Source, this is redundant work, bad code and frankly an old habit that will disappear soon.
Step 2: Create a Controller
I'm going to show you a really straight-forward one just to get your question sorted.
public class FooController
{
[HttpPost]
public async Task<IActionResult> Create([FromBody] Object item)
{
if (item == null) return BadRequest();
var newItem = new Object(); // create the object to return
if (newItem != null) return Ok(newItem);
else return NotFound();
}
}
Step 3: Check your Content-Type
and Accept
You need to make sure that your Content-Type
and Accept
headers in your request are set properly. In your case (JSON), you will want to set it up to be application/json
.
If you want your WebAPI to respond as JSON as default, regardless of what the request header is specifying you can do that in a couple ways.
Way 1
As shown in the article I recommended earlier (Formatting Response Data) you could force a particular format at the Controller/Action level. I personally don't like this approach... but here it is for completeness:
Forcing a Particular Format If you would like to restrict the response formats for a specific action you can, you can apply the
[Produces] filter. The [Produces] filter specifies the response
formats for a specific action (or controller). Like most Filters, this
can be applied at the action, controller, or global scope.[Produces("application/json")]
public class AuthorsController
The
[Produces]
filter will force all actions within the
AuthorsController
to return JSON-formatted responses, even if other
formatters were configured for the application and the client provided
anAccept
header requesting a different, available format.
Way 2
My preferred method is for the WebAPI to respond to all requests with the format requested. However, in the event that it doesn't accept the requested format, then fall-back to a default (ie. JSON)
First, you'll need to register that in your options (we need to rework the default behavior, as noted earlier)
options.RespectBrowserAcceptHeader = true; // false by default
Finally, by simply re-ordering the list of the formatters that were defined in the services builder, the web host will default to the formatter you position at the top of the list (ie position 0).
More information can be found in this .NET Web Development and Tools Blog entry
Related Topics
C# Create/Modify/Read .Xlsx Files
How to Draw a Rounded Rectangle as the Border for a Rounded Form
Split String, Convert Tolist<Int>() in One Line
C#:Is Variance (Covariance/Contravariance) Another Word for Polymorphism
Mvcbuildviews Not Working Correctly
App.Config for a Class Library
How to Add Xmlinclude Attribute Dynamically
Change Color and Font for Some Part of Text in Wpf C#
Does Distinct() Method Keep Original Ordering of Sequence Intact
Add Shape Information to a Listview When Its Created
How to Programmatically Click a Button in Wpf
Add Two Integers Using Only Bitwise Operators
Does a Locked Object Stay Locked If an Exception Occurs Inside It
How to Generate a Cryptographically Secure Pseudorandom Number in C#
Selecting a Textbox Item in a Listbox Does Not Change the Selected Item of the Listbox