In this article we will discuss Web API design, concepts, functionality, and comparison Web APIs and WCF.
1. Implementing a Web API project
Let's start with a simple example. We use Visual Studio 2012 as the development environment. Our first step is to create a ASP.net MVC 4.0 project based on the Web API template, as shown in Figure 1: Figure 1: Create a asp.net MVC 4 project based on the Web API templates
Next, we create a simple data model in the Model folder. Right-click the Model folder in the Solution Resources folder and choose Add-> Class, as shown in Figure 2:
Figure 2: Adding a new data model
This is just a tutorial, I define a product data model, as shown in table 1.
public class Product
{public
int Id
{get; set;}
public string Name
{get; set;}
public string Category
{get; set;}
Public decimal price
{get; set;}}
Table 1: Defining Product models
After creating the product data model, we can create a new API controller in the Controllers folder to process the product data model. By default, an MVC project based on the Web API template can add two controllers: one inherits from the Controller class and the other inherits from the Apicontroller class. Right-click the Controllers folder in the Solution Resources folder, select Empty API controller in the pop-up window, and add a new controller. As shown in Figure 3:
Figure 3: Adding the empty API controller
The controller code is shown in table 2:
public class Productscontroller:apicontroller {list<product> products = new list<product> ();
Public ienumerable<product> getallproducts () {getproducts ();
return products; private void GetProducts () {products.
ADD (new Product {Id = 1, Name = "Television", category= "Electronic", price=82000}); Products.
ADD (new Product {Id = 2, Name = "Refrigerator", Category = "Electronic", Price = 23000}); Products.
ADD (new Product {Id = 3, Name = "mobiles", Category = "Electronic", Price = 20000}); Products.
ADD (new Product {Id = 4, Name = "laptops", Category = "Electronic", Price = 45000}); Products.
ADD (new Product {Id = 5, Name = "IPads", Category = "Electronic", Price = 67000}); Products.
ADD (new Product {Id = 6, Name = "Toys", Category = "Gift Items", Price = 15000}); } public ienumerable<product> Getproducts (int selectedid) {if (products). Count () > 0) {return products.
Where (p => p.id = = Selectedid);
else {getproducts (); return products.
Where (p => p.id = = Selectedid); }
}
Table 2: Adding Apicontroller classes to instance projects
Run the project and connect to the API through "/api/products", for example: Http://localhost:8747/api/Products. You can also pass the Selectedid parameter to invoke the GetProducts method, for example: http://localhost:8747/api/Products?SelectedId=2
2. Ways to pass complex objects to the Web API
Passing a simple object in the Web API is easy, but in most cases you need to pass a complex object parameter. You can pass objects by [Fromurl] or [Frombody] properties. The [Frombody] property reads data from the request body. However, this property can only be used once in the parameter list of a method.
Let's use code snippets to explain the importance of using complex parameters, as shown in table 3:
public class Samplecontroller:apicontroller
{
///<summary>
///get time
///</summary>< c4/>///<param name= "T" ></param>
///<returns></returns> public
string GetTime T)
{return
string. Format ("Received time: {0}:{1}.{ 2} ", T.hour, T.minute, T.second);
}
public class time
{public
int Hour {get; set;}
public int Minute {get; set;}
public int Second {get; set;}
}
Table 3: Passing complex parameters to a method
Now let's use the Hour,minute and second parameters to pass the value to the GetTime method. You can see that it went wrong and returned a null reference error. As shown in Figure 4:
Figure 4: An error occurred while calling the GetTime method
Although we are aware that input values need to be associated with a time object, the API method does not correctly map input values to object properties. Now let's see if we can modify the code to include complex objects in the URL query string with the [Fromuri] attribute. In the following fragment we declare the [Fromuri] property before the time object:
public string GetTime ([Fromuri] time t)
{-------------------}
Now that we pass the same value through this method, there will be different results, as shown in Figure 5:
Figure 5: The call to the GetTime method succeeded
3. Using the HttpClient API HttpClient is an extensible API that allows access to any service or Web site via HTTP. This httpclient was introduced to the WCF Web API and is now available in the ASP.net Web API in the. NET Framework 4.5. You can use httpclient in the background and services (for example, WCF) to access Web API methods.
This snippet creates a HttpClient object and accesses the API methods in the instance asynchronously.
Asynchronous accessing of Web API method Async Task GetData () {StringBuilder result = new
StringBuilder (); Define the HttpClient object using (httpclient client = new HttpClient ()) {//D Efine the "base" of the MVC application hosting the Web API//accessing the Web API from the same s Olution client.
baseaddress = new Uri (HttpContext.Current.Request.Url.AbsoluteUri); Define the serialization used JSON/XML/ETC client.
DEFAULTREQUESTHEADERS.ACCEPT.ADD (New Mediatypewithqualityheadervalue ("Application/json")); Call the method httpresponsemessage response = client. Getasync ("Api/products").
result; if (response.
Issuccessstatuscode) {//Convert the result into business object var products = Response. Content.reaDasasync<ienumerable<product>> ().
result; foreach (var p in products) {result. Append (String.
Format ("{0}---[Price: {1} Category: {2}]", P.name, P.price, p.category)); } else {result. Append (String. Format ("Error code:-{0} error Details: {1}", (int) response. StatusCode, Response.
Reasonphrase)); } data. Text = result.
ToString (); }
Table 4: Create a HttpClient object to access the API methods in the instance
4. Use jquery to access the Web API in HTML5 Web applications, you can use jquery to access the Web API directly. You can use the Getjson () method to invoke the API to get the results, and then remove the business object. jquery recognizes the business pairs associated with the internal field, for example: Data[i]. Price.
This snippet demonstrates finding data from the Product API method and displaying the data to a table.
Table 5: Using jquery to find data from the Product API method
5. Passing parameters in jquery In addition, you can use jquery to pass parameters, looking for data from the Web API method. jquery supports multiple methods for passing parameters. The first method is to use a single parameter. The following code snippet shows how to pass a single parameter:
$.getjson ("Api/products",
{selectedid: ' 4 '},
function (data) { ...});
You can also pass multiple arguments in a collection, as follows:
$.getjson ("Api/products",
{selectedid: ' 4 ', Name: ' TV '},
function (data) { ...});
Alternatively, you can put the parameters directly in the URL, and demonstrate the following:
$.getjson ("Api/products?selectedid =4",
function (data) { ...});
The first method separates the query characters and parameters from the URL, which applies to complex or multiple data passes. The second method is more appropriate for one or two parameters.
6. The Web API code framework asp.net scaffolding is a asp.net Web application code generation framework. Visual Studio contains preinstalled code generators for MVC and Web API projects. Visual Studio automatically generates the required API code to perform a variety of operations in the specified data model and data source.
The Entity Framework, based on the code framework, verifies how the code framework works in Web API projects, and we can use the Entify framework to define our databases and generate Web API methods. First, we need to add a ado.net Entity Data model to define the data. Our instance data will be based on two tables, couse and status, as shown in Figure 6:
Figure 6: Adding a Entity Data Model based on the course and status table
After defining the data model, we can generate a Web API controller that is consistent with the data model. Right-click Controller and then click Add Controller to eject the Add Controller window. In the Controler name input box, enter controller name. From the template Drop-down list, select the API controller with Read/write actions, the Using Entity framework template, as shown in Figure 7:
Figure 7: Adding a controller based on the data model
Next, select a table from the Model class Drop-down list and specify the data context in the Datasheet class Drop-down list. Table 6 shows the code generated automatically by the Coursecontroller API controller. It contains the get,put,post, and the Delete method, which is consistent with model.
public class Coursecontroller:apicontroller {private Sampledbentities db = new sampledbentities (); Get Api/course public ienumerable<course> getcourses () {return db.
Courses.asenumerable (); }//Get API/COURSE/5 public Course getcourse (int id) {Course Course = db.
Courses.single (c => c.courseid = ID);
if (course = = null) {throw new Httpresponseexception (Request.createresponse (Httpstatuscode.notfound));
return course; }//Put API/COURSE/5 public httpresponsemessage putcourse (int id, Course Course) {if (! Modelstate.isvalid) {return request.createerrorresponse (httpstatuscode.badrequest, modelstate);} if (ID!= course. CourseID) {return request.createresponse (httpstatuscode.badrequest);} db.
Courses.attach (course); Db.
Objectstatemanager.changeobjectstate (course, entitystate.modified); try {db.
SaveChanges (); The catch (Dbupdateconcurrencyexception ex) {return request.createerrorresponse HttpStatuscode.notfound, ex);
Return Request.createresponse (Httpstatuscode.ok); }//POST Api/course public httpresponsemessage postcourse (Course Course) {if (modelstate.isvalid) {db.
Courses.addobject (course); Db.
SaveChanges ();
Httpresponsemessage response = Request.createresponse (httpstatuscode.created, course); Response. Headers.location = new Uri (Url.link ("Defaultapi"), new {id = course.
CourseID}));
return response;
else {return Request.createerrorresponse (httpstatuscode.badrequest, modelstate);}} DELETE API/COURSE/5 public httpresponsemessage deletecourse (int id) {Course Course = db.
Courses.single (c => c.courseid = ID); if (course = = null) {return request.createresponse (httpstatuscode.notfound);} db.
Courses.deleteobject (course); try {db.
SaveChanges (); catch (Dbupdateconcurrencyexception ex) {return request.createerrorresponse (Httpstatuscode.notfound, ex);
Request.createresponse (Httpstatuscode.ok, course); } protected override void Dispose (bool disposing) {db.
Dispose (); Base.
Dispose (disposing); }
}
Table 6:coursecontroller API Controller generated code
The Web API code framework functionality reduces the developer's ability to work with common additions and deletions.
7. asp.net Web API Routing rules
The Web API uses a unified routing selector (URIS) to implement multiple behaviors. There is a webapiconfig file in the App_start folder of the Solution Resource folder that defines a different routing mechanism for the Web API. This mechanism is based on HTTP methods, actions, and properties. However, we can define our own routing mechanism to support custom paths.
For example, in our Web API Project example, we use/api/products to receive product details. However, we want to replace with api/products/getallproducts, you can modify the default routing logic, you need to include {action} in the URI, the code snippet is as follows:
Config. Routes.maphttproute (
name: "Defaultapi",
routetemplate: "Api/{controller}/{action}/{id}",
defaults: New {id = routeparameter.optional}
);
After updating the rule, we can use the ActionName property on the Web API method to specify the action name, and the snippet is as follows:
[ActionName ("Getallproducts")]
Public ienumerable<product> getallproducts ()
Note: You can use the [Nonaction] property to indicate that the Web API method is not an API action method.
We can use an HTTP method or Acceptverbs property to specify which HTTP action to use to connect to the Web API method. The following code fragment uses the HttpGet and HttpPost methods:
[HttpGet]
Public ienumerable<product> getproducts (int selectedid)
{...}...}
[HttpPost]
public void Addproduct (Product p)
{...}....
Another way, using the Acceptsverbs property, the following code breaks:
[Acceptverbs ("Get", "put")]
Public ienumerable<product> getproducts (int selectedid)
Web API 2 advocates the use of attributes whenever possible. For more information, see the file: Attribute Routing in Web API v2.
8. Serialization of
The Web API supports a variety of serialization methods, including Xml,json, and Messagepack. In the following sections, we will look at how to implement these three methods and compare them. Before we learn, we modify the instance code of the Web API project to return large chunks of data so that we can better understand and compare the effects of serialization. Table 7 shows how to use the GetProducts () method to return large chunks of data.
private void GetProducts ()
{for
(int i = 0; i < 5000, i++)
{products
. ADD (new Product {Id = i, Name = "Product- " +i,
Category = "The asp.net and Visual Web Developer teams have Sed the asp.net and Web Tools 2012.2 Update, which extends the existing ASP.net and runtime new web adds to Visual Studio 2012. Whether You use Web Forms, MVC, Web APIs, or any of the other ASP.net technology, there are something cool in this update for you. , Price
= 1});
}
Table 7: Updating the GetProducts () method
9. Using JSON serialization
The Web API uses JSON as the default serialization method. This way, when you run the Web API project, it automatically returns to JSON format. For example, to receive the products details, you only need to use http://<;<server>>:<<port>>/api/Products to get the results of the JSON format.
using XML SerializationUsing XML serialization in Web API projects, you must modify the Global.aspx file to insert the following two lines of code in the Application_Start () method:
GlobalConfiguration.Configuration.Formatters.RemoveAt (0);
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
After you execute the XML serialization method, you can use Http://<;<server>>:<<port>>/api/Products to view the details.
using Messagepack serializationTo use the Messagepack method, you must first install Messagepack (http://msgpack.org/). Messagepack can be added and managed by NuGet. You can also download the source code from the GitHub and build the application in Visual Studio.
When you install the Messagepack, refer the MsgPack.dll to the Messagepack library. Next, create a custom media type format that is used to serialize Web API data. Table 8 is the media type format (https://gist.github.com/filipw/3693339) displayed on the GitHub.
public class Mediatypeformattercompatiblemessagepack:mediatypeformatter
{
private readonly str