Thursday, August 11, 2016

Developing an ASP.NET Web API_part 2 (end)

Web API Service Structure for Mobile Devices

Now that the basic idea of how Actions from Controllers can be exposed through the API is understood, let's look at how an API Service can be designed for clients.


The ASP.NET Web API request pipeline receives requests from the client application, and an action method in a controller will be invoked. The action method will, in turn, invoke the Business layer for fetching or updating data, which, in turn, invokes the Repository class to return data from the database.

Based on this design pattern, let's create a sample API that exposes a list of Classified items as a service to its clients.

Create a class called ClassifiedModel inside the Models folder.
  1. public class ClassifiedModel
  2.     {
  3.         public int ClassifiedID { get; set; }
  4.         public string ClassifiedTitle { get; set; }
  5.         public string ClassifiedDetail { get; set; }
  6.         public DateTime CreatedDate { get; set; }
  7.         public string ClassifiedImage { get; set; }
  8.     }
Create two folders BLL and DAL representing the Business Logic Layer and Data Access Layer.

Create a class called ClassifiedRepository inside the DAL folder where we will hard-code some data for the classified list and expose the list through a static method.
  1. public class ClassifiedRepository
  2.     {
  3.         //list of Classified Objects
  4.         public static List<ClassifiedModel> classifiedList;
  5.  
  6.         /// <summary>
  7.         /// get list of classified models
  8.         /// </summary>
  9.         /// <returns></returns>
  10.         public static List<ClassifiedModel> GetClassifiedsList()
  11.         {
  12.             if (classifiedList == null
  13.             || classifiedList.Count == 0)
  14.             {
  15.                 CreateClassifiedsList();
  16.             }
  17.             return classifiedList;
  18.         }
  19.  
  20.         /// <summary>
  21.         /// Init a list of classified items
  22.         /// </summary>
  23.         private static void CreateClassifiedsList()
  24.         {
  25.             classifiedList = new List<ClassifiedModel>()
  26.             {
  27.                 new ClassifiedModel()
  28.                 {
  29.                     ClassifiedID = 1,
  30.                     ClassifiedTitle = "Car on Sale",
  31.                     ClassifiedDetail = "Car details car details car details",
  32.                     CreatedDate = DateTime.Now,
  33.                     ClassifiedImage = "/carImageUrl.jpg"
  34.                 },
  35.  
  36.                 new ClassifiedModel()
  37.                 {
  38.                     ClassifiedID = 2,
  39.                     ClassifiedTitle = "House on Sale",
  40.                     ClassifiedDetail = "House details house details house details",
  41.                     CreatedDate = DateTime.Now,
  42.                     ClassifiedImage = "/houseImageUrl.jpg"
  43.                 },
  44.  
  45.                 new ClassifiedModel()
  46.                 {
  47.                     ClassifiedID = 3,
  48.                     ClassifiedTitle = "Room for rent",
  49.                     ClassifiedDetail = "Room details room details room details",
  50.                     CreatedDate = DateTime.Now,
  51.                     ClassifiedImage = "/roomImageUrl.jpg"
  52.                 },
  53.  
  54.                 new ClassifiedModel()
  55.                 {
  56.                     ClassifiedID = 4,
  57.                     ClassifiedTitle = "Tree on Sale",
  58.                     ClassifiedDetail = "Tree details tree details tree details",
  59.                     CreatedDate = DateTime.Now,
  60.                     ClassifiedImage = "/treeImageUrl.jpg"
  61.                 }
  62.  
  63.             };
  64.         }
  65.     }
Let's add another class ClassifiedService inside the BLL folder now. This class will contain a static method to access the repository and return business objects to the controller. Based on the search parameters, the method will return the list of classified items.
  1. public class ClassifiedService
  2.     {
  3.         public static List<ClassifiedModel> GetClassifieds(string searchQuery)
  4.         {
  5.             var classifiedList = ClassifiedRepository.GetClassifiedsList();
  6.  
  7.             if (!string.IsNullOrEmpty(searchQuery))
  8.             {
  9.                 return (from m in classifiedList
  10.                         where m.ClassifiedTitle.StartsWith(searchQuery, StringComparison.CurrentCultureIgnoreCase)
  11.                         select m).ToList();
  12.             }
  13.             return classifiedList;
  14.         }       
  15.     }
Finally, now we will create our Web API controller for the classified listing related methods.

Similar to how we created our first TestController, let's create an API controller with empty read/write actions called ClassifiedsController and add the following two Action methods.
  1. public class ClassifiedsController : ApiController
  2.     {
  3.         public List<ClassifiedModel> Get(string id)
  4.         {
  5.             return ClassifiedService.GetClassifieds(id);
  6.         }
  7.         public List<ClassifiedModel> Get()
  8.         {
  9.             return ClassifiedService.GetClassifieds("");
  10.         }
  11.     }
Now, we have two Actions exposed through the API. The first GET method will be invoked if there is a keyword to be searched that is passed along with the request. If there is no input parameter, then the second GET method will be invoked. Both methods will return a list of our Classified model objects.

Do not forget to add all the required references to the namespaces in each of the added class files. Build the project, and we are ready to test both of these methods now.

To display results containing the search parameter "house", hit the following URL in the browser: http://localhost/TestAPI/api/classifieds/get/house.

We should get the following response in the browser:


To see the entire list of classifieds, hit the URL without passing any parameters: http://localhost/TestAPI/api/classifieds/get/.

You should see the following result:


We can add any number of Actions and Controllers in the same manner as desired by the clients.

Content Negotiation

Up to now, we've seen examples of API that send XML responses to the clients. Now let's look at other content types like JSON and Image response, which fall under the topic of Content Negotiation.

The HTTP specification (RFC 2616) defines content negotiation as “the process of selecting the best representation for a given response when there are multiple representations available." Thanks to Web API's Content Negotiation feature, clients can tell Web API services what content format it accepts, and Web API can serve the client with the same format automatically, provided that the format is configured in Web API.

Requesting JSON Format
The HTTP Accept header is used to specify the media types that are acceptable to the
client for the responses. For XML, the value is set as "application/xml" and for JSON "application/json".

In order to test our API with the HTTP Accept headers, we can use the extensions available for the browsers that allow us to create custom HTTP requests.

Here, I am using an extension called HTTP Tool available for Mozilla Firefox to create the Accept header that specifies JSON as the response type.


As you can see from the image, the response that is being received is in JSON format.

Image File as Response
Finally, let's see how we can send an Image file as a response through Web API.

Let's create a folder called Images and add an image called "default.jpg" inside it, and then add the following Action method inside our ClassifiedsController.
  1. public HttpResponseMessage GetImage()
  2.         {
  3.             byte[] bytes = System.IO.File
  4.                            .ReadAllBytes
  5.                            (
  6.                                 HttpContext.Current.Server
  7.                                 .MapPath("~/Images/default.jpg")
  8.                            );
  9.              
  10.             var result = new HttpResponseMessage(HttpStatusCode.OK);
  11.  
  12.             result.Content = new ByteArrayContent(bytes);
  13.  
  14.             result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
  15.             return result;
  16.         }
Also, these two namespaces should be included: System.Web, System.Web.Http.

Here we are creating an HTTP response using the HttpResponseMessage class and setting the image bytes as the response content. Also, we are setting the Content-Type header to "image/png".

Now, if we call this action in our browser, Web API will send our default.jpg image as a response: http://localhost/TestAPI/api/classifieds/Getimage/.

Conclusion

In this tutorial, we looked at how ASP.NET Web API can easily be created and exposed to clients as Action methods of MVC Controllers. We looked at the default and custom routing system, created the basic structure of a real-time business application API Service, and also looked at different response types.
Written by Sovit Poudel

If you found this post interesting, follow and support us.
Suggest for you:

REST WCF Service in ASP.NET

Visual Basic.Net Tutorials for Beginners

No comments:

Post a Comment