How can I code a Created-201 response using IHttpActionResult
?
IHttpActionResult
has only these options
What I am doing now is this code below, but I would like to use IHttpActionResult
and not HttpResponseMessage
public IHttpActionResult Post(TaskBase model)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, model);
response.Headers.Add("Id", model.Id.ToString());
return ResponseMessage(response);
}
If your view derives from ApiController
, you should be able to call the Created
method from base class to create such a response.
Sample:
[Route("")]
public async Task<IHttpActionResult> PostView(Guid taskId, [FromBody]View view)
{
// ... Code here to save the view
return Created(new Uri(Url.Link(ViewRouteName, new { taskId = taskId, id = view.Id })), view);
}
return Content(HttpStatusCode.Created, "Message");
Content is returning NegotiatedContentResult. NegotiatedContentResult is implements IHttpActionResult.
A similar problem: If you want to send NotFound with the message.
return Content(HttpStatusCode.NotFound, "Message");
Or:
return Content(HttpStatusCode.Created, Class object);
return Content(HttpStatusCode.NotFound, Class object);
In ASP.NET Core, an IActionResult
can be returned. This means you can return a ObjectResult
with a 201 status code.
[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] CreateModel createModel)
{
// Create domain entity and persist
var entity = await _service.Create(createModel);
// Return 201
return new ObjectResult(entity) { StatusCode = StatusCodes.Status201Created };
}
Alternatively, to what Chris is suggesting, what you can do is return an IActionResult, using or " StatusCode " method, the following way:
[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] CreateModel createModel)
{
// Create domain entity and persist
var entity = await _service.Create(createModel);
// Return 201
return StatusCode(StatusCodes.Status201Created, entity);
}
I know this is an old thread but you might want to take a look at my solution here . Its a little more than needed but sure will do the job.
Steps:
Define a custom attribute:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class UniqueIdAttribute: Attribute
{
}
Decorate the uniquely identifying property of your model with a custom attribute:
public class Model
{
public List<Model> ChildModels { get; set; }
[UniqueId]
public Guid ModelId { set; get; }
public Guid ? ParentId { set; get; }
public List<SomeOtherObject> OtherObjects { set; get; }
}
Add a new Created(T yourobject);
method to a BaseController which inherits from ApiController. Inherit all your controllers from this BaseController:
CreatedNegotiatedContentResult<T> Created<T>(T content)
{
var props =typeof(T).GetProperties()
.Where(prop => Attribute.IsDefined(prop, typeof(UniqueIdAttribute)));
if (props.Count() == 0)
{
//log this, the UniqueId attribute is not defined for this model
return base.Created(Request.RequestUri.ToString(), content);
}
var id = props.FirstOrDefault().GetValue(content).ToString();
return base.Created(new Uri(Request.RequestUri + id), content);
}
Its pretty simple without having to worry about writing so much in every method. All you got to do is just call Created(yourobject);
The Created() method would still work if you forget to decorate or cannot decorate your model(for some reason). The location header would miss the Id though.
Your unit test for that controller should take care of this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.