Working with ActionResults in Web API

By FoxLearn 1/2/2025 7:37:02 AM   15
Action Results in ASP.Net Web API allow you to return data as an `HttpResponseMessage` object from controller methods, helping build stateless and RESTful HTTP services.

Getting started

To create a Web API project, start by creating a blank ASP.Net project in Visual Studio 2022 and selecting the Web API template.

After saving the project, right-click the Controllers folder, choose "Add" -> "Controller", and select "Web API 2 Controller – Empty". Name the controller (e.g., "DefaultController") and save it.

Let's create an entity class named Customer.

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

Next, add the following method to the CustomerController:

public CustomActionResult<Customer> Get()
{
    Customer customer = new Customer
    {
        Id = 1,
        Name = "John Doe",
        Email = "[email protected]"
    };

    return new CustomActionResult<Customer>(HttpStatusCode.OK, customer);
}

Note the usage of the CustomActionResult class while returning data from the controller method. We will create the CustomActionResult class to ensure the code compiles, and implement it later:

public class CustomActionResult<T> : IHttpActionResult
{
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }
}

Working with ActionResults

Your Web API controller can return any one of the following value types:

  1. HttpResponseMessage: Converts the return value into an HTTP response message and returns it.
  2. IHttpActionResult: Simplifies unit testing and wraps the creation of an HttpResponseMessage object.
  3. void: Returns an empty HTTP response with status code 204.
  4. Other types: Uses a media formatter to serialize and return data with a status code of 200.

The following code snippet shows how you can return an HttpResponseMessage from your Web API controller method:

[Route("customer")]
public HttpResponseMessage Get()
{
    HttpResponseMessage message = Request.CreateResponse<Customer>(HttpStatusCode.OK, customer);
    return message;
}

Creating a Custom ActionResult

To create a custom ActionResult class, implement the IHttpActionResult interface and override the ExecuteAsync method.

Here’s a code snippet for creating a custom action result using Generics:

public class CustomActionResult<T> : IHttpActionResult
{
    private HttpStatusCode statusCode;
    private T data;

    public CustomActionResult(HttpStatusCode statusCode, T data)
    {
        this.statusCode = statusCode;
        this.data = data;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(CreateResponse(this.statusCode, this.data));
    }

    private HttpResponseMessage CreateResponse(HttpStatusCode statusCode, T data)
    {
        HttpRequestMessage request = new HttpRequestMessage();
        request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
        return request.CreateResponse(statusCode, data);
    }
}

Consuming the Web API

To consume the Web API, create a console application and install the WebApiContrib.Formatting.ProtoBuf package via NuGet.

Here’s an example code for consuming the Web API:

static void Main(string[] args)
{
    var client = new HttpClient { BaseAddress = new Uri("http://localhost:37019/") };
    HttpResponseMessage response = client.GetAsync("api/Customer").Result;

    if (response.IsSuccessStatusCode)
    {
        Customer customer = response.Content.ReadAsAsync<Customer>().Result;
        Console.WriteLine("Id = " + customer.Id + " Name: " + customer.Name + " Email: " + customer.Email);
    }
    else
    {
        Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
    }

    Console.ReadKey();
}