Quantcast
Channel: ASP.Net Web API – Bit of Technology
Viewing all articles
Browse latest Browse all 37

What is New in ASP.Net Web API 2 – Part 2

$
0
0

In the previous post we’ve covered ASP.Net Web API 2 attribute routing, in this post we’ll complete covering new features, we’ll start by discussing the new response return type IHttpActionResult then cover the support for CORS.

Source code is available on GitHub.

ASP.Net Web API 2 IHttpActionResult:

As we talked before ASP.Net Web API 2 has introduced new simplified interface named IHttpActionResult, this interface acts like a factory for HttpResponseMessage, it comes with custom built in responses such as (Ok, BadRequest, NotFound, Unauthorized, Exception, Conflict, Redirect).

Let’s modify the GetCourse(int id) method to return IHttpActionResult instead of HttpResponseMessage as the code below:

[Route("{id:int}")]
public IHttpActionResult GetCourse(int id)
{
	Learning.Data.LearningContext ctx = null;
	Learning.Data.ILearningRepository repo = null;
	try
	{
		ctx = new Learning.Data.LearningContext();
		repo = new Learning.Data.LearningRepository(ctx);

		var course = repo.GetCourse(id, false);
		if (course != null)
		{
			return Ok<Learning.Data.Entities.Course>(course);
		}
		else
		{
			return NotFound();
		}
	}
	catch (Exception ex)
	{
		return InternalServerError(ex);
	}
	finally
	{
		ctx.Dispose();
	}
}

Notice how we’re returning Ok (200 HTTP status code) with custom negotiated content, the body of the response contains JSON representation of the returned course. As well we are returning NotFound (404 HTTP status code) when the course is not found.

But what if want to extend the NotFound() response and customize it to return plain text message in response body? This is straight forward using IHttpActionResult interface as the below:

Construct our own Action Result:

We want to build our own NotFound(“Your custom not found message”) action result, so we need to add a class which implements IHttpActionResult, let’s add new file named NotFoundPlainTextActionResult as the code below:

public class NotFoundPlainTextActionResult : IHttpActionResult
{
    public string Message { get; private set; }
    public HttpRequestMessage Request { get; private set; }

    public NotFoundPlainTextActionResult(HttpRequestMessage request, string message)
    {
        this.Request = request;
        this.Message = message;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(ExecuteResult());
    }

    public HttpResponseMessage ExecuteResult()
    {
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.NotFound);

        response.Content = new StringContent(Message);
        response.RequestMessage = Request;
        return response;
    }
}

public static class ApiControllerExtension
{
    public static NotFoundPlainTextActionResult NotFound(ApiController controller, string message)
    {
        return new NotFoundPlainTextActionResult(controller.Request, message);
    }
}

By looking at the code above you will notice that the class “NotFoundPlainTextActionResult” implements interface “IHttpActionResult”, then we’ve added our own implementation to the method “ExecuteAsync” which returns a Task of type HttpResponseMessage. This HttpResponseMessage will return HTTP 404 status code along with the custom message we’ll provide in the response body.

In order to be able to reuse this in different controllers we need and new class named ApiControllerExtension which contains a method returns this customized Not Found response type.

Now back to our” CoursesController” we need to change the implementation of the standard NotFound() to the new one as the code below:

if (course != null)
	{
		return Ok<Learning.Data.Entities.Course>(course);
	}
	else
	{
		return eLearning.WebAPI2.CustomIHttpActionResult.ApiControllerExtension.NotFound(this, "Course not found");
	}

You can read more about extending IHttpActionResult result by visiting Filip W. post.

ASP.Net Web API 2 CORS Support:

Enabling Cross Origin Resource Sharing in ASP.Net Web API 2 is simple, once it is enabled any client sending AJAX requests from webpage (on a different domain) to our API will be accepted.

By default CORS assembly doesn’t exist within ASP.NET Web API 2 assemblies so we need install it from NuGet, so open your NuGet package console, and type the following 

Install-Package Microsoft.AspNet.WebApi.Cors -Version 5.0.0
 once the package is installed open “WebApiConfig” class and add the following line of code inside the register method
config.EnableCors();
 by doing this we didn’t enable CORS yet, there are different levels to enable CORS on ASP.Net Web API, levels are:

1. On controller level

You can now add attribute named EnableCors on the entire controller so by default every action on this controller will support CORS as well, to do this open file “CoursesController” and add the highlighted line of code below:

[RoutePrefix("api/courses")]
[EnableCors("*", "*", "GET,POST")]
public class CoursesController : ApiController
{
	//Rest of implementation is here
}

The EnableCors attribute accept 3 parameters, in the first one you can specify the origin of the domain where requests coming from, so if you want to allow only domain www.example.com to send requests for your API; then you specify this explicitly in this parameter, most of the cases you need to allow * which means all requests are accepted from any origin. In the second parameter you can specify if you need a certain header to be included in each request, so you can force consumers to send this header along with each request, in our case we will use * as well. The third parameter is used to specify which HTTP verbs this controller accepts, you can put * as well, but in our case we want to allow only GET and POST verbs to be called from requests coming from different origin.

In case you want to exclude a certain action in the controller from CORS support you can add the attribute DisableCors to this action, let we assume we want to disable CORS support on method GetCourse so the code to disable CORS support on this action will be as the below:

[Route("{id:int}")]
[DisableCors()]
public IHttpActionResult GetCourse(int id)
{
	//Rest of implementation is here
}

2. On action level

Enabling CORS on certain actions is fairly simple, all you want to do is adding the attribute EnableCors on this action, as well EnableCors accepts the same 3 parameters we discussed earlier. Enabling it on action level will be as the below code:

[Route(Name = "CoursesRoute")]
[EnableCors("*", "*", "GET")]
public HttpResponseMessage Get(int page = 0, int pageSize = 10)
{
	//Rest of implemntation is here
}

 3. On the entire API

In some situations where you have many controllers and you want to allow CORS on your entire API, it is not convenient to visit each controller and add EanbleCors attribute to it, in this situation we can allow it on the entire API inside the Register method in Class WebApiConfig, so open your WebApiConfig class and add the code below:

//Support for CORS
EnableCorsAttribute CorsAttribute = new EnableCorsAttribute("*", "*", "GET,POST");
config.EnableCors(CorsAttribute);

By adding this we enabled CORS support for every controller we have in our API, still you can disable CORS support on selected actions by adding DisableCors attribute on action level.

Source code is available on GitHub.

That’s all for now!

Thanks for reading and please feel free to drop any comment or question if there is nothing clear. Happy Coding!

The post What is New in ASP.Net Web API 2 – Part 2 appeared first on Bit of Technology.


Viewing all articles
Browse latest Browse all 37

Trending Articles