Click here to Skip to main content
15,867,568 members
Articles / Hosted Services / Azure

WebAPI in Service Fabric

Rate me:
Please Sign up or sign in to vote.
3.00/5 (4 votes)
17 Jun 2018CPOL3 min read 28K   327   8   3
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:

XML
<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.

Image 1

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

Image 2

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:

C#
/// <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:

C#
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:

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Sweden Sweden
I work as Senior Developer mainly in Microsoft environment and my strenghts are SQL, C#, Vue.js, Angular and ReactJS.

Comments and Discussions

 
QuestionThis was a tip... Pin
OriginalGriff7-May-18 6:43
mveOriginalGriff7-May-18 6:43 
AnswerRe: This was a tip... Pin
Gunnar S7-May-18 19:17
Gunnar S7-May-18 19:17 
GeneralRe: This was a tip... Pin
Alaa Ben Fatma17-May-18 8:19
professionalAlaa Ben Fatma17-May-18 8:19 
Generally, a publication is considered as a TIP if the publisher's intention is to put some light on one monospecific point. For example : How to activate Intellisense, How to change the theme of visual studio. However, an article is when the writer digs deeper into the aspects of the chosen subject.

Here is a simple comparison:

TIP: How to serialize an object
Article: How to create a custom serializer

All in all, this is my basic understanding of the whole context. Who knows, maybe there exist other explanations. Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.