Consuming ASP.Net 5 Web API With CRUD Functions in Windows 10 Native Application

Introduction and Background

I have been developing Windows 10 applications ever since I became a Windows 10 Insider but ASP.NET was left behind for a very long time, likely to be 2 years. ASP.NET has also received many updates so I thought it was time for me to start working on ASP.NET also. ASP.NET 5 has many great features:

  1. Fast start-up
  2. Just-in-time compilation
  3. Actually, compilation now works as you type in the code, or as you change the debugging settings (the debugging settings also require you to re-compile the project, build some might say)
  4. Shorter memory benchmark
  5. Above all, XML is getting out, JSON is getting into the frameworks and most settings now use JSON

In this article I will create a stand-alone Web API, without HTML pages because I am not showing how to create a small API for your website, instead a full-featured API (standalone API) for your project that needs to be hosted. There are common differences between them as shown in Table 1.

ASP.NET Web Application + Web API Standalone Web API (No Web App)
Good if you want to have both flavors for your client. This would allow you to use an HTML application and an API for clients, mobiles and software apps. More powerful framework and being stand-alone would allow your developers to focus on only one part, HTTP RESTful clients.
They both are hosted on the same server, same hosting environment, same URL This option doesn't include applications, you will host only the API. You can host it anywhere, even inside your own network or send it to clients to run on their networks!
Cross-platform data sharing plus user-interface. Web APIs are not intended for user-interfaces. They are simple command-based services.
Cost double time, developers must work for maintaining the application's user-interface for the web application part and the Web API part. The user-interface part is removed, so all you need to focus on is the logic of your application.

Table 1: Differences between ASP.NET Web Application + Web API and ASP.NET Web API alone

Now, let me ask you a few things. Do you:

  1. Really need to continue usign old web programming in which you would need to maintain the look and feel of your application across browsers? IE is still the horror!
  2. Need your clients to install offline applications on their machines so that they can run and execute functions with fancy buttons and that you do not need to worry about security that much?
  3. Want to cut short your financial budget and team size?

If you answered yes, then trust me. ASP.NET MVC application is not what you are looking for. Straight away create a small Web API and use it for your purposes. It is still based on ASP.NET MVC so that the technical knowledge you have for ASP.NET MVC can be implemented for the ASP.NET Web API. A few good things that come with Web API are:

  1. No worry about user-interface. You build the user-interface for the client. Most are simple console applications. But Windows Presentation Foundation and Windows Forms can also be used to consume those APIs. Which means that graphical support is even better with these frameworks in hand.

  2. Cross-platform support. A Web API can be consumed by any device, platform, OS, location and network. Thus, it prevents you from writing a separate environment and service for every platform and so on. It hosts on the same location, the rest is assured by the network.

  3. Smaller memory benchmark compared to other web services and websites. Although you can write web applications to ask for data, the Web API can allow you to write native applications (good performance!) and at the same time implement a native experience.

Windows 10, on the other hand, is a new OS using the same old Windows Runtime technology. Windows Runtime allows you to write applications that are compiled to a native library providing you much better performance than any other .NET application can. Windows Runtime is the core of your Universal Applications Platform.

In this article I will create two projects, one for each of:

  1. An ASP.NET 5's Web API (stand-alone, do not confuse yourself with the Web API + Web Application template).

    This would serve as the API we will make some requests to, to get the data for our application's logic.

  2. A Windows 10 native Universal application.

This will be the client for our server. Note that we would create the user-interface in only this Windows 10 application. The look and feel would follow the native conventions and themes. The rest will be captured by the API at run-time.

Understanding ASP.NET 5 Web API and Windows 10

Before we get started, it is better to actually understand what ASP.NET 5 has for us in its API and what would Windows 10 serve us as. We will dissect a few things of them each and learn them in a procedure.

ASP.NET 5 Web API

ASP.NET 5 is a new version of ASP.NET by Microsoft. Web API has been introduced for ASP.NET for a very long time and we are well aware of what a RESTful API is. ASP.NET's Web API allows us to use HTTP verbs to communicate with the API. Since ASP.NET's Web API is based on much of a MVC pattern (ASP.NET MVC) you can define action methods for each of the type. Attributes are used to target an action.

  1. // HttpGet attribute notifies that this should be run if request has GET method  
  2. [HttpGet]  
  3. public List<string> Get() { 
  4. return _list; // Suppose _list is of type List<string> with some data 
  5. }  
This way we can generate responses for our clients. Also note that unlike the default MVC we are not returning an ActionResult that allows us to return a View (with or without a Model). Instead we return native objects that are returned, either in JSON or XML format.

Personally, I recommend using JSON format instead of XML because of its compact size. You should consider reducing the size of traffic usage, bytes large in size may throttle the network or take much time. Which is not something to happen in your applications.

The rest of the code is just the basics of C# and the MVC pattern. We create a model, add some logic to it to retreive the data and we return (or manipulate) the data using our API.

Windows 10 Universal Apps

Now to introduce ourselves to Windows 10. Windows 10 is just a fancy term that I used in the title. What I actually mean is using Windows Runtime to create a client. I won't be using .NET's applications such as Windows Presentation Foundation or Windows Forms. Instead a native Universal application, Windows Runtime based one.

Windows Runtime has many helpful libraries for us to communicate over the network. Windows.Web.Httpnamespace of Windows Runtime is one of them. It exposes us to a HttpClient object in a Runtime application. It is indeed similar to HttpClient of the .NET Framework, but with better performance because the Runtime is built on top of native code, unlike the .NET Framework.

The user-interface for it is native, too. I will use the Windows.UI.Xaml.Controls library to render various controls on the screen.
  1. Page
  2. TextBlock
  3. TextBox
  4. Button
  5. ListView

Adding just a few lines of C# code would make it our client for the API. Next, I will show you how to create a Web API and how to configure it to run!

CRUD Introduction

CRUD is just an abbreviation of Create, Read, Update and Delete. An application with CRUD functionality is simply an application that allows you to:

  1. Create a new record.
  2. Read all records, or one record at a time.
  3. Update those records.
  4. Delete a record.

In our API, I will create the same functions. They will allow us to perform CRUD functions on our model. There is no card under my sleeve when I am writing a CRUD API. It is just a fancy term, nothing else.

Bonus library: Newtonsoft.Json

Since we will work with JSON data, I recommend you use the Newtonsoft.Json library when working with JSON data. In my application, I have also used this library. Trust me, it saves you from most of troubles.

You can get it from NuGet by running the following NuGet Package Manager command:

PM> Install-Package Newtonsoft.Json

NuGet would install the package for you. In the source code that I will provide along with this article, the package is already included for you.

Getting started

I hope by now you have understood what ASP.NET 5 is and what Windows 10's Universal Apps are. If so, you may continue to program a client/server architecture based on both of these new technologies on the block!

Setting up the environment

Before we start, you need to set up your environment for development. I want you to ensure a few things:

  1. Do you have Windows 10?

    Programming a Windows 10 application requires you to be present on a Windows 10 operating system. So, get a copy of Windows 10, by upgrading or by becoming an Insider!

  2. Do you have Visual Studio 2015?

    Visual Studio 2015 is required to program a Windows 10 application. You can get a Visual Studio Community Edition license for free to start programming an application. ASP.NET 5 also comes shipped with Visual Studio 2015, so Visual Studio 2015 is a must.

    Once you have answered yes to the preceding questions continue you can roceed to the next section in which I explain the creation of both an API and a client for your own purposes.

Creating the Web API

  1. I recommend you first develop the API rather than writing the code for your client. Writing the API would benefit you in a number of ways.

  2. Having the API already set up would help you to do the scratch work for clients. In a way that you will know what methods are provided in the API, what parameters I need to pass and so on.

  3. You won't need to make changes to the API again just to ensure that the client and API are working together. Editing the API for one client would also make it potentially problematic for other clients and devices.

  4. You must always configure your clients to work with the API, not the other way around. You will have multiple clients, connecting through multiple networks, devices and platforms. Your API is static, it won't change. That is why, be sure your API is open enough that anyone can connect. Thus, simple HTTP verbs and a very clear action method is enough.

    Tip: Try creating interfaces and objects when working in the API. This way, upon a request you will be able to send that request to another background thread or an interface that would handle the request and then return the data back to you. Hard-coding everything right inside the request handler would make it harder to be edited once your model gets to enterprise-level complexity.

    In the future sections I will show you how to ensure that the model is not kept complex, rather a very simple and straight-forward one that is capable of further programming to make it even better!

Create a new Web API project

In Visual Studio 2015 (which ever edition you have, I have Community) create a new web application project. Be sure that you select from ASP.NET 5 templates and not the ASP.NET 4 templates. Among them, select the Web API and then continue with your project.



Figure 1: Web API

At this stage, your project would only have one single controller, ValuesController in my case. Just edit that out, change the name of class to UserController and (if you want to tidy up a few things) change the file name to UserController.cs. Leave everything else as it is until we have created a model to work around with when making requests and accepting requests from clients.

Creating and editing the Model

Since the Web API is mostly dependant on ASP.NET MVC, you will see the Model-view-controller pattern being applied here. Similarly, that controller of our Web API (recall the UserController) and the Model (that we will create now) form a part of that MVC pattern. As already said, there are no Views in this case because we will work around with only HTTP requests and no HTML rendering to be used for View.

I have created a basic example of objects for you that I will be using. A simple model structure for our object, User. I have another class (with all the static members) that will serve us for our model data source. The following is the class diagram for them:



Figure 2: Model

It is quite clear, User has the properties that can be used for our data. We can edit them in the list to create a unique list of users for our data source. Further, all we need is a model with some static functions to allow us to perform the actions. The Model allows us to manipulate the data source of ours (in this article case it is just a list of users).

User class

  1. // Actual data model  
  2. public class User  
  3. {  
  4. public int ID { getset; }  
  5. public string Name { getset; }  
  6. public bool Gender { getset; }  
  7. public string[] Interests { getset; }  
  8. }  
Model class
  1. // A class to work-around with out data source  
  2. public class Model {  
  3.     // Example data source  
  4.     private static List < User > users = new List < User > () {  
  5.         new User {  
  6.             ID = 1,  
  7.             Name = "Afzaal Ahmad Zeeshan",  
  8.             Gender = true,  
  9.             Interests = new string[] {  
  10.                 "Programming""Songs"  
  11.             }  
  12.         },  
  13.         new User {  
  14.             ID = 2,  
  15.             Name = "Shani",  
  16.             Gender = true,  
  17.             Interests = new string[] {  
  18.                 "Eminem""Eating"  
  19.             }  
  20.         },  
  21.         new User {  
  22.             ID = 3,  
  23.             Name = "Daniyal Ahmad Rizwan",  
  24.             Gender = true,  
  25.             Interests = new string[] {  
  26.                 "Games""Movies"  
  27.             }  
  28.         },  
  29.         new User {  
  30.             ID = 4,  
  31.             Name = "Marshall Bruce Mathers III",  
  32.             Gender = true,  
  33.             Interests = new string[] {  
  34.                 "Rapping""Parenting"  
  35.             }  
  36.         }  
  37.     };  
  38.   
  39.     // C part of CRUD  
  40.     public static void CreateUser(User user) {  
  41.         users.Add(user);  
  42.     }  
  43.   
  44.     // R part of CRUD  
  45.     public static List < User > GetAll() {  
  46.         return users;  
  47.     }  
  48.   
  49.     public static User GetUser(int id) {  
  50.         return users.Find(x = > x.ID == id); // Find one user and return him  
  51.     }  
  52.   
  53.     // U part of CRUD  
  54.     public static void UpdateUser(int id, User user) {  
  55.         users.Remove(users.Find(x = > x.ID == id)); // Remove the previous User  
  56.         users.Add(user);  
  57.     }  
  58.   
  59.     // D part of CRUD   
  60.     public static void DeleteUser(int id) {  
  61.         users.Remove(users.Find(x = > x.ID == id)); // Find and remove the user  
  62.     }  
  63. }  
Regarding the preceding code, isn't it quite clear as to what each function does? There is no ambiguity and the function and role is also clear. We would definitely use these functions in our controllers to execute various aspects of actions based on HTTP requests and their verbs.

In addition to the function, property (data source) users is also static. The reason behind that is if it was not set to static, every new request would re-initialize the data source to initial (4 object) list only. Which would undo any changes that we perform in the application. Indeed this was just an overhead data source. In your application you would have a database supporting your application. The database would have other functions and features for your project. In those cases, you won't need to even create these classes and objects. You will be able to get a driver or controller for your database. For example, System.Data.SqlClient for SQL Server databases.

Final touch to the API

Now to update the API controllers to handle the request and pass the control over to the model to manipulate the state of the application to return a response if the client is waiting for a response. The controller is as simple as 4 methods, one for each request type.
 

Figure 3: UserController

The source code for the controller is:
  1. [Route("api/[controller]")]  
  2. public class UserController: Controller {  
  3.     // GET: api/user  
  4.     [HttpGet]  
  5.     public IEnumerable < User > Get() {  
  6.         return Model.GetAll();  
  7.     }  
  8.   
  9.     // GET api/user/5  
  10.     [HttpGet("{id}")]  
  11.     public User Get(int id) {  
  12.         return Model.GetUser(id);  
  13.     }  
  14.   
  15.     // POST api/user  
  16.     [HttpPost]  
  17.     public void Post([FromForm] string value) {  
  18.         var user = JsonConvert.DeserializeObject < User > (value); // Convert JSON to Users  
  19.         Model.CreateUser(user); // Create a new User  
  20.     }  
  21.   
  22.     // PUT api/user/5  
  23.     [HttpPut("{id}")]  
  24.     public void Put([FromForm] int id, [FromForm] string value) {  
  25.         var user = JsonConvert.DeserializeObject < User > (value);  
  26.         Model.UpdateUser(id, user);  
  27.     }  
  28.   
  29.     // DELETE api/user/5  
  30.     [HttpDelete("{id}")]  
  31.     public void Delete(int id) {  
  32.         Model.DeleteUser(id);  
  33.     }  
  34. }  
Have a look again, the same basic functions. One for each of type of request that the user may send. These functions are handled by that Http attribute. It tells the API which method to execute for which HTTP verb. 

Request URL HTTP verb Response
GET http://www.example.com/api/user GET [Users]
ET http://www.example.com/api/user/1 Get {User}
POST http://www.example.com/api/user POST void | bool | object
PUT http://www.example.com/api/user PUT void | bool | object
DELETE http://www.example.com/api/user DELETE void | bool | object

Table 2: HTTP requests, methods and responses

Table 2 has many things that you need to understand before reading more! A few things I will make clear here for you.

  1. In the first case (with no ID appended), the result is an array. Notice that the convention for return in the first two rows is JSON (or JavaScript). In the first case an array is returned. In the second one, a single instance of an object is returned. Due to space limitations, I did not write the objects in their formal representation, sorry!

  2. In case of POST, PUT and DELETE I have returned void. You can (depending on your needs) return a bool or object to work around with the response on client-side. Suit yourself.

This way, these requests are sent to the server, mapped to an action and then executed. The response is then streamed to a client over the network that then renders it. Ok, enough of the API, now let us consider writing the client application in the Windows 10 framework.

Configuring the server settings

If you are willing to continue with the default settings then you should feel free to skip this section. But you find yourself handy when editing out the website configurations. It would allow you to use a handy URL and a few other settings. Consider going to the properties page and under the Debug (or Web) edit the settings.

In my case, I had set a start-up URL to /api/user and the port was changed to 1234. Easy to remember.

Creating the client in Windows 10 application

Now in this section I will show you how to create a Windows 10 application that acts as a client to our API. I will have template pages all created and ready for the API to fill the data into the pages. I would have a few pages and man logical expressions to actually run the logic. I won't show how everything is connected at the back-end, just a few high-level abstractions of the application will be shown. You can (if eager to test) download the source code provided and test the project by building it and running it on your own machine.

Note: Be sure the API is running when your start the Windows application. Otherwise, it won't work, or worse, start annoying you.

Now open Visual Studio 2015 and create a new project for Windows 10. You will find it under Visual C# → Windows → Universal. Create an empty application. You need not bug yourself with a complex framework for such a basic application as it stands.

Creating the application views

You may consider making the views for your application. In the source code I have added the following 3 pages for our application. 

  • View: This page would refer to the Read of CRUD.
  • CreateOrUpdate: This page will be used to either creare or update of the CRUD. Since both of these forms would provide the same fields for input, I thought, why create two separate pages, just create one and on a condition change their values! Helpful though.
  • Delete: Finally, this would prompt you to delete the record.
I won't show the source code of the XAML markup because that would make the article too long to read and this article is not about XAML or Windows 10, instead it is more about server-client applications using ASP.NET 5 Web API and Windows Runtime. So, I am focusing on Windows Runtime APIs more. If you are interested in application code, please download the source code and tinker with it. Feel free to share it or port it in your own applications also.

First step to be a client

Now the main part of Windows Runtime programming. The Windows Runtime is not the .NET Framework and the objects that you are aware of in the .NET Framework are not available in the Windows Runtime. The Windows Runtime has its own API sets and libraries. However a portable library of the .NET Framework is also available for the Windows Runtime.

In this application, I will be using a HttpClient object of the Windows.Web.Http namespace rather than usingHttpClient of the System.Net.Http namespace. They are entirely different ones, so please don't get yourself confused. Windows.Web.Http.HttpClient is a Windows Runtime object, whereas System.Net.Http.HttpClient is a .NET object. Since this object also implements IDisposable, we can use it in a using block for better results.

Most of the times, the code would just be like:
  1. using(var client = new HttpClient()) {  
  2.     /* 
  3.      * Send requests here 
  4.      * client.GetAsync(); For GET HTTP 
  5.      * client.PostAsync(); // For POST HTTP 
  6.      * Parameters are still required to be passed. 
  7.      **/  
  8. }  
The rest of the stuff is simply application state logic that shouldn't be explained since it would bring up some confusion. That is why I am intent on providing only the code relavent to CRUD operations among our client-server model.

Initiating CRUD requests

In HTTP API, various verbs are used to initiate requests and to tell the server what to do. In this section I will show you how to actually send requests to the API with a specific HTTP method along with some data, so servers know what to do with the data. You must note that HTTP GET and HTTP DELETE requests do not need any additional data. You can pass a parameter in the URL such as DELETE http://www.example.com/api/user/5 and the server would know to delete the user at ID 5. PUT and POST methods require you to pass some data that must be saved or stored.

HTTP PUT or HTTP POST

HTTP PUT and HTTP POST both update content on the server that must be used to actually implement the storing of the data. Some use POST to upload data and PUT to update it, some use PUT to store the data and POST to update it.

The actual answer to this ambiguity is their idempotency that one is actually intended to update the data and which one stores the data.

From a very great thread I got the answer.

HTTP Post
  1. x++  
HTTP PUT
  1. x = 5  
Easy, isn't it? HTTP POST is not idempotent, it is intended to work when you want it to, let's say, add more records to the database. Increments the records always. HTTP PUT on the other hand creates a new record (if it doesn't exist) then continues to update it (if it already exists).

Setting up the application

I created some application properties as to be able to work around with the API and the state of the application, all in one application.
  1. public static Uri BaseUri = new Uri("http://localhost:1234/api/user"); // base API URL; UserController  
  2. public static Frame RootFrame { getset; } // RootFrame to be updated for different Views  
  3. public static User ActiveUser { getset; } // Active User to be worked with.   
Creating or updating the user

The first step I will explain is creating the user. Creating the user takes a form that can be then reused for updating the user. I will use the same page but just with a little alteration. So, it would serve me for both purposes.

Creating the user

When creating, the form will be empty. We will fill in the details and then we will send those details, using HttpClient, to the API.
 
 

Figure 4: Create a new user

Upon submission, the data is passed to the API by serializing the content to JSON.

Updating the user

Updating the user is just a similar process, the only difference is that in this case the form won't be empty. Instead the application would show us the previous data that we can edit and then click "Update".
 


Figure 5: Update the user

The source code for them is similar, that is why I did not share it before. What happens is, when the button is clicked (in both cases) the data is serialized and a request is sent to the API with an appropriate HTTP method.
  1. private void Button_Click(object sender, RoutedEventArgs e) {  
  2.     if ((sender as Button).Content.ToString() == "Cancel") {  
  3.         // Go to default page   
  4.         App.RootFrame.Navigate(typeof(MainPage));  
  5.         return// and cancel the event.  
  6.     }  
  7.   
  8.     // Otherwise  
  9.     var user = new User {  
  10.         ID = Convert.ToInt32(userId.Text),  
  11.         Name = name.Text,  
  12.         Gender = (gender.IsChecked == true) ? true : false,  
  13.         Interests = interests.Text.Split(',')  
  14.     };  
  15.   
  16.     using(var client = new HttpClient()) {  
  17.         var content = JsonConvert.SerializeObject(user);  
  18.   
  19.         if (create == null || create == true) {  
  20.             // Send a POST  
  21.             Task task = Task.Run(async() = > {  
  22.                 var data = new HttpFormUrlEncodedContent(  
  23.                 new Dictionary < stringstring > {  
  24.                     ["value"] = content  
  25.                 });  
  26.                 await client.PostAsync(App.BaseUri, data); // sends POST request  
  27.             });  
  28.             task.Wait();  
  29.         } else {  
  30.             // Send a PUT  
  31.             Task task = Task.Run(async() = > {  
  32.                 var data = new HttpFormUrlEncodedContent(  
  33.                 new Dictionary < stringstring > {  
  34.                     ["value"] = content, ["id"] = App.ActiveUser.ID.ToString()  
  35.                 });  
  36.                 await client.PutAsync(App.BaseUri, data); // sends PUT request  
  37.             });  
  38.             task.Wait();  
  39.         }  
  40.     }  
  41.   
  42.     App.RootFrame.Navigate(typeof(MainPage)); // Finally navigate back  
  43. }  
Reading the users

Reading the users is (IMO) the simplest task to perform on the API. You send a request (with no additional data) and the API returns a list of users.

To fetch the records from the API, use the following code:

  1. var response = "";  
  2. Task task = Task.Run(async () =>  
  3. {  
  4. response = await client.GetStringAsync(App.BaseUri); // sends GET request  
  5. });  
  6. task.Wait(); // Wait  
  7. listView.ItemsSource = JsonConvert.DeserializeObject<List<User>>(response); // Bind the list  
The result for this will be a list, I used a ListView control to define my own custom layout for the list rather than default ToString to be called.

 

 

Figure 6: View User detail

You can see the new user that we created in the last section available there. Right now it doesn't show many details, clicking on it (SelectionChanged) will help us.
 


Figure 7: New user

The second one (although it doesn't have separate code) comes from the ActiveUser property of the application. I changed the view when the selection changes that enables me to change the view and show the details that I need to.

Deleting the users

The final and another easy task is to delete the users. It takes just a DELETE request and no additional data.
 


Figure 8: Delete a user

Upon clicking the Yes button, the application executes the following code:
  1. // Send a request to delete the user  
  2. using(var client = new HttpClient()) {  
  3.     Task task = Task.Run(async() = > {  
  4.         await client.DeleteAsync(App.BaseUri + "/" + App.ActiveUser.ID.ToString());  
  5.     });  
  6.     task.Wait();  
  7. }  
  8. App.RootFrame.Navigate(typeof(MainPage));  
Quite simple though

So, as from this application it is clear how easy it is to actually create cross-platform clients that consume a central API. It allows us to create a native application on different platforms and send HTTP requests to the API. Another good thing is that applications all can have a native feel and look. We don't need to work so hard to fix the cross-platform and cross-device layout and other similar problems that arise in web applications.

Download the source code from the article and try the applications out yourself. You can use it for your own purposes also, feel free to share it.


Similar Articles