Reputation: 2629
I need to return an ActionResult
containing an object, however, I do not inherit from ControllerBase
, so I'm unable to use the Ok
, BadRequest
etc. methods. How can I do this?
More info:
The reason I do not inherit from ControllerBase
is that I hold a generic Response object, which contains a method that returns an ActionResult
. The logic to determine which ActionResult should be returned will be in this method.
I've tried:
ContentResult
This gives me the option to provide a value, but only accepts a string Content
value.
StatusCodeResult
This doesnt give me the option to provide an object to use as the value.
OkResult
, BadRequest
etc.
This doesnt give me the option to specify a value.
My Code:
public enum ResponseStatus
{
Ok,
BadRequest,
// ...
}
public class ResponseObject<T>
{
public ResponseStatus Status { get; set; }
public T Value { get; set; }
public ActionResult ToActionResult()
{
switch (Status)
{
case ResponseStatus.Ok:
return new SomethingThatIsOk(this); // this doesnt exist, I dont know to return, hence the question
case ResponseStatus.BadRequest:
return new SomethingThatIsBadRequest(this); // this doesnt exist, I dont know to return, hence the question
// ...
}
}
}
Upvotes: 1
Views: 6069
Reputation: 247153
There are multiple derived results that can be used to get the desired behavior.
public class ResponseObject<T> {
public ResponseStatus Status { get; set; }
public T Value { get; set; }
public ActionResult ToActionResult() {
switch (Status) {
case ResponseStatus.Ok:
return new OkObjectResult(this);
case ResponseStatus.BadRequest:
return new BadRequestObjectResult(this);
// ...
}
}
}
Use the one appropriate to your desired status.
ObjectResult Class has a few derived classes that worked for this scenario,
Microsoft.AspNetCore.Mvc.AcceptedAtActionResult
Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult
Microsoft.AspNetCore.Mvc.AcceptedResult
Microsoft.AspNetCore.Mvc.BadRequestObjectResult
Microsoft.AspNetCore.Mvc.ConflictObjectResult
Microsoft.AspNetCore.Mvc.CreatedAtActionResult
Microsoft.AspNetCore.Mvc.CreatedAtRouteResult
Microsoft.AspNetCore.Mvc.CreatedResult
Microsoft.AspNetCore.Mvc.NotFoundObjectResult
Microsoft.AspNetCore.Mvc.OkObjectResult
Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult
Microsoft.AspNetCore.Mvc.UnprocessableEntityObjectResult
System.Web.Http.BadRequestErrorMessageResult
System.Web.Http.ExceptionResult
System.Web.Http.InvalidModelStateResult
System.Web.Http.NegotiatedContentResult<T>
System.Web.Http.ResponseMessageResult
but I would suggest you review the API documentation for any other classes that may suit your needs.
All the ControllerBase
does is wrap the creation of the result in a method
/// <summary>
/// Creates an <see cref="OkObjectResult"/> object that produces an <see cref="StatusCodes.Status200OK"/> response.
/// </summary>
/// <param name="value">The content value to format in the entity body.</param>
/// <returns>The created <see cref="OkObjectResult"/> for the response.</returns>
[NonAction]
public virtual OkObjectResult Ok([ActionResultObjectValue] object value)
=> new OkObjectResult(value);
/// <summary>
/// Creates an <see cref="BadRequestObjectResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <param name="error">An error object to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestObjectResult BadRequest([ActionResultObjectValue] object error)
=> new BadRequestObjectResult(error);
Upvotes: 3