Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WebAPI in Service Fabric

0.00/5 (No votes)
17 Jun 2018 2  
Moving ASP.NET WebAPI code to Service Fabric Cluster

Introduction

A good start to learn about Service Fabric is here.

NB: The application is removed from Azure. Please download the code and run it in your local cluster.

Background

This article builds on this article where you find the original CarClient and CarAPI projects which in this article are moved to a Service Fabric Cluster.

Using the Code

Before deploying and running this application in local cluster, make sure that http://localhost:80 and http://localhost:83 are not already used on your computer. If http://localhost:80 is already in use, change to some other free port in CarClient ServiceManifest.xml. E.g., to use port 8080, write:

<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8080" />

Then start the program in the browser with http://localhost:8080.

Please note that this code is only tested on Google Chrome. The JavaScript in the client runs perfectly on Google Chrome, but I have noticed problems with Internet Explorer and FireFox.

To run this sample, you need an Azure Account and your own Azure SQL Server app. You must update the connection string to point to your own Azure SQL Server. You also need Service Fabric Explorer and Service Fabric Cluster Manager which you get when you install the service fabric SDK.

SQLite has been replaced with Azure SQL Server and the CarClient and CarAPI projects are now stateless service fabric services.

To create this solution by Visual Studio, a Service Fabric Application has been chosen as solution template.

In the solution, two stateless ASP.NET Core projects have been added: one WebAPI and one Web Application as shown below:

The code from the older CarAPI and CarClient have been added to the default projects with as few modifications as possible. The solution can be run in both an Azure cluster and a local cluster. The Azure cluster is created by Visual Studio. When creating a SF cluster from Visual Studio, you get a cluster using certificate security. This forces the application to use https for the reverse proxy in Azure as opposed to running it locally where http must be used.

In Azure, the URL used for CarAPI was http://carfabric.northeurope.cloudapp.azure.com:83/ and in the local cluster, the URL http://localhost:83/ is used. This URL is used by JavaScript in CarClient for retrieving and updating data in the database. CarAPI can be checked in local cluster with http://localhost:83/swagger.

For CarClient, the same URLs are used except the port number is changed to 80. The URL is passed via the environment variable ApiAddressConnectionString which is defined in the ServiceManifest.xml for CarClient. How the value is defined when running the app locally respectively in Azure can be seen in Cloud.xml and Local1.xml in folder ApplicationParameters. The code for getting the reverse proxy address is as follows:

/// <summary>
/// Constructs a reverse proxy URL for a given service
/// Example: http://localhost:19081/CarFabric/CarAPI/
/// </summary>
///<param name="serviceName"></param>
/// <returns></returns>
public static Uri GetProxyAddress(Uri serviceName)
{
    string ApiAddress = Environment.GetEnvironmentVariable("ApiAddressConnectionString");
    if (ApiAddress.IndexOf("localhost") > 0)
    {
        return new Uri($"http://localhost:19081{serviceName.AbsolutePath}/");
    }
    else
    {
        return new Uri($"https://localhost:19081{serviceName.AbsolutePath}/");
    }
}

This code is found in project CarClient, file Utils.cs.

Comparing the HTTP Client code between the old traditional solution and the service fabric solution shows the differences clearly.

New Service Fabric code:

namespace CarClient
{
    public static class Utils
    {
        public static async Task<T> Get<T>(string url)
        {
            Uri serviceName = CarClientApp.GetCarAPIServiceName();
            Uri proxyAddress = GetProxyAddress(serviceName);
            HttpClientHandler handler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = 
                      HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
            };
            using (var client = new HttpClient(handler) { BaseAddress = proxyAddress })
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add
                         (new MediaTypeWithQualityHeaderValue("application/json"));
                var response = await client.GetAsync(url);
                var content = await response.Content.ReadAsStringAsync();
                return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
            }
        }

The old code is as follows:

namespace CarClient
{
    public static class Utils
    {
        private static readonly Uri Endpoint = new Uri("http://localhost:54411//");
        public static async Task<T> Get<T>(string url)
        {
             using (var client = new HttpClient() { BaseAddress = EndPoint })
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add
                            (new MediaTypeWithQualityHeaderValue("application/json"));
                var response = await client.GetAsync(url);
                var content = await response.Content.ReadAsStringAsync();
                return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
            }
        }

For implementation details, please download CarFabric.zip and read the code.

Points of Interest

When creating a SF cluster from Visual Studio, you get a cluster using certificate security. This forces the application to use https for the reverse proxy in Azure as opposed to running it locally where http must be used.

History

  • 8th May, 2018: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here