Weather (state,county)

The ASP.NET Web API


As we all know working with Ajax is really fun, a very challenging job, and we become more satisfy when we see the UI behave very interactively, with out the page getting fully load. It does also help in reducing the amount of data send to and from the server back to client. But it become more challenging when we keep on increasing the number of Ajax call, we need some thing more then JsonResult return. This is the time we need to look and start using ASP.NET WEB API.

ASP.NET WEB API leverages both the web standards :
  1. HTTP / JSON
  2. XML
ASP.NET WEB API  provide a simple way to build and expose REST-based services. Like ASP.NET MVC it also uses some of the core concepts like :
  1. Routing
  2. Controllers
  3. Action Results

The only difference that i see is that web api is involve working with data as opposed to creating HTML markup in MVC.

Building a Data Service

Adding an ASP.NET Web API controller to your application is almost exactly like adding an ASP.NET MVC controller. The following sections walk you through the process by showing how you can add a Web API controller to the Ebuy reference application.

Before you begin, you’ll need a folder in which to store your new Web API controller. Web API controllers can live just about anywhere, so it’s really up to you to come up with a convention that works for you. For instance, i prefer to create a new folder named Api in the root of the website, but you can feel free to store your Web API controllers in the Controllers folder right next to the ASP.NET MVC controllers—as long as you don’t have any naming conflicts, ASP.NET will be able to tell them apart just fine.

To add a new Web API controller, simply right-click on the folder you’d like to add the service to (in our case, the Api folder) and choose the “Controller…” context menu item. This will bring up the same Add Controller dialog that you use to create ASP.NET MVC controllers, only this time you will choose the “API controller with empty read/write actions” template rather than one of the ASP.NET MVC controller templates. To begin, give the new controller a name. For this example, we’ll use the name AuctionsController.cs.

When you’re done, click the Add button to add the Web API controller to your project. Below contains the code for the new Web API controller.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace Ebuy.Website.Api
{
    public class AuctionsDataController : ApiController
    {
        // GET api/auctions
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/auctions/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/auctions
        public void Post(string value)
        {
        }

        // PUT api/auctions/5
        public void Put(int id, string value)
        {
        }

        // DELETE api/auctions/5
        public void Delete(int id)
        {
        }
    }
}

Registering Web API Routes

Before we can use this new controller, however, we must register it with the ASP.NET routing framework so that it can begin to receive requests.
As with ASP.NET MVC, ASP.NET Web API requests are based on routing URLs to their corresponding controller actions. In fact, ASP.NET Web API routes are registered in almost exactly the same way as ASP.NET MVC routes are registered. The only difference is that instead of the RouteTable.MapRoute() helper extension, Web API routes use the RouteTable.MapHttpRoute() extension.

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
); 
 
This is because the Web API Framework figures out the controller action to execute using convention over configuration.

Note

You are not required to begin your route with the literal api path segment—feel free to change the Web API route pattern to whatever route you like, as long as it doesn’t conflict with any other routes registered in the same application.
The same rules that apply to ASP.MVC routing also apply to Web API data services—be careful that your route patterns aren’t too specific, or overly vague.

Leaning on Convention over Configuration

Like ASP.NET MVC, ASP.NET Web API makes heavy use of convention over configuration to lighten the workload involved in creating web data services. For example, instead of requiring you to annotate each method with an attribute such as HttpPostAttribute to identify what type of requests an action may handle (as you must do with ASP.NET MVC controller actions), ApiController methods rely on names that correspond to the standard HTTP actions.
Using this convention makes it really easy to perform CRUD (Create, Read, Update, Delete) operations on a resource (entity). The standard HTTP actions and their corresponding CRUD operations are:
GET (Read)
Retrieves the representation of the resource
PUT (Update)
Updates an existing resource (or creates a new instance)
POST (Create)
Creates a new instance of a resource
DELETE (Delete)
Deletes a resource

Note

The PUT method will replace the entire entity. To support partial updating, the PATCH method should be used instead.
Interacting with an ASP.NET Web API data service is incredibly easy.
For example, the snippet below shows how to use the jQuery $.getJSON() method to make a GET request to the /api/auction service, which returns a collection of auctions serialized in JSON format:

Overriding Conventions

It’s important to note that the controller action naming convention only applies when the name corresponds to one of the standard REST actions (GET, POST, PUT, and DELETE). However, if you’d like to name your methods differently but still leverage the rest of the Web API’s functionality, you can apply the AcceptVerbsAttribute—or its aliases, such as HttpGetAttribute or HttpPostAttribute—to the Web API controller methods, just as you would apply the attribute on an ASP.NET MVC controller action.
The following code snippet shows this in action:
[HttpGet]
public Auction FindAuction(int id)
{
}
In this example, we’ve decided to break the REST convention and name our controller action FindAuction rather than using the conventional Get method name. In order to do this, we applied the HttpGetAttribute to the FindAuction controller action to indicate that this action handles GET requests.

Hooking Up the API

Now let’s walk through setting up the Web API controller that we created earlier so it can perform CRUD operations on auctions.
In order to access the Ebuy database, an instance of the application’s data repository class is passed in to the AuctionsDataController constructor:
public class AuctionsDataController : ApiController
{
    private readonly IRepository _repository;

    public AuctionsDataController(IRepository repository)
    {
        _repository = repository;
    }
}
By default, Web API controllers require a default (empty parameter) constructor. Since an IRepository needs to be passed in to the controller, a custom dependency resolver class needs to be initialized during application startup:
GlobalConfiguration.Configuration.DependencyResolver =
new NinjectWebApiResolver(kernel);
Here is an example of a custom dependency resolver that is using a Ninject IoC container. Since Web API controllers are created per request, the custom resolver needs to create a new dependency scope (e.g., NinjectWebApiScope) for each request:
using System.Web.Http.Dependencies;
using Ninject;

public class NinjectWebApiResolver : NinjectWebApiScope, IDependencyResolver
{
    private IKernel kernel;

    public NinjectWebApiResolver(IKernel kernel) : base(kernel)
    {
        this.kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NinjectWebApiScope(kernel.BeginBlock());
    }
}
Here are the contents of the custom Ninject scope class. When a Web API controller is requested, the GetService() method will be called; Resolve() will handle injecting the repository when it creates an instance of the controller:
                                                                                                                                                                     
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using Ninject.Activation;
using Ninject.Parameters;
using Ninject.Syntax;

public class NinjectWebApiScope : IDependencyScope
{

    protected IResolutionRoot resolutionRoot;

    public NinjectWebApiScope(IResolutionRoot resolutionRoot)
    {
        this.resolutionRoot = resolutionRoot;
    }

    public object GetService(Type serviceType)
    {
        return resolutionRoot.Resolve(this.CreateRequest(serviceType)).SingleOrDefault();
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return resolutionRoot.Resolve(this.CreateRequest(serviceType))
    }

    private IRequest CreateRequest(Type serviceType)
    {
        return resolutionRoot.CreateRequest(serviceType,
                                null,
                                new Parameter[0],
                                true,
                                true);
    }

    public void Dispose()
    {
        resolutionRoot = null;
    }
}
The following code shows the fully implemented Web API controller that has been updated to use the repository to peform CRUD operations on the Auctions class:
public class AuctionsDataController : ApiController
{
    private readonly IRepository _repository;

    public AuctionsDataController(IRepository repository)
    {
        _repository = repository;
    }

    public IEnumerable<Auction> Get()
    {
        return this._repository.All<Auction>();
    }

    public Auction Get(string id)
    {
        return _repository.Single<Auction>(id);
    }

    public void Post(Auction auction)
    {
        _repository.Add<Auction>(auction);
    }

    public void Put(string id, Auction auction)
    {
        var currentAuction = _repository.Single<Auction>(id);

        if (currentAuction != null)
        {
            currentAuction = Mapper.DynamicMap<Auction>(auction);
        }
    }

    public void Delete(string id)
    {
        _repository.Delete<Auction>(id);
    }
}

No comments:

Powered by Blogger.