devklick
devklick

Reputation: 2629

Return new ActionResult with value without using ControllerBase

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:


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

Answers (1)

Nkosi
Nkosi

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);

Source

/// <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);

Source

Upvotes: 3

Related Questions