After we covered the basics of ServiceStack in part one and how to set up a service in part two of this series. Today we’ll go through how the C#-Client can be utilized to make communication between applications even easier. The sourcecode for todays article is available GitHub. If you missed one of the previous parts, feel free to check out Part 1 – What is ServiceStack and why should I use it? or Part 2 – Building a Simple Service.

Implementation of the Client

First, we will need to add a new project to our solution. This will function as the client-side application. For the sake of simplicity, I decided to create a console application. After the new project has been created, we have to install the ServiceStack nuget-package. Another required step is to add a reference to our base project. This allows gives us access to the request and response DTOs.

After the project has been set up, the C#-Client can easily be utilized. The following snippet is all that it takes to send a request to the service and save its response. Don’t forget to update the clients URL to match the address of your service.

JsonServiceClient jsonServiceClient = new JsonServiceClient("http://localhost:61401");
var response = jsonServiceClient.Post<ExpenseResponse>(new Expense { Amount = 500 });

In order to make the example a little more valuable, we will improve the service from the last part a little bit.

Service Improvements: Using Sessions

As you can see in the following snippet, I have installed a session mechanism that manages the current requests. I specified a general total of 1000, whereby each request reduces this amount by the requested withdrawals. Also, each request increments the request counter. I limit the amount of withdrawals to the total amount available. If more money is withdrawn, the service will not execute the request and the user will be informed. To keep track of the session data, I created another class called TrackingData, which is shown below the Post-method of our service.

public object Post(Expense request)
{
    var Session = base.SessionBag;

    var trackingData = (TrackingData)Session["Expenses"];
    if (trackingData == null)
        trackingData = new TrackingData { TotalBalance = 1000, WithdrawalsAmount = 0 };

    if(trackingData.TotalBalance >= request.Amount)
    {
        trackingData.Withdrawals += request.Amount;
        trackingData.TotalBalance -= request.Amount;
        trackingData.WithdrawalsAmount++;

        Session["Expenses"] = trackingData;

        return new ExpenseResponse
        {
            Amount = request.Amount,
            Total = trackingData.TotalBalance,
            WithdrawalsAmount = trackingData.WithdrawalsAmount,
            Status = "OK"
        };
    }
    else
    {
        return new ExpenseResponse
        {
            Amount = request.Amount,
            Total = trackingData.TotalBalance,
            WithdrawalsAmount = trackingData.WithdrawalsAmount,
            Status = "Balance too low"
        };
    }
}

Let’s add some further modification to be able to increase our withdrawals. These modification reads a users input as long as he enters valid integers. When entering anything else, the loop will exit and the program stops.

public class TrackingData
{
    public double Withdrawals { get; set; }
    public double TotalBalance { get; set; }
    public int WithdrawalsAmount { get; set;
}

With these adjustments it is possible to generate successive requests. After several requests, postman delivers a result similar to the following.

{
    "Amount": 200,
    "Total": 600,
    "Status": "OK",
    "WithdrawalsAmount": 3
}

Further Shortcuts

Another small change I would like to make concerns the DTOs themselves. By specifying a return value using the IReturn interface, you do not need to specify the response type on the client side.

[Route("/Expense")]
[Route("/Expense/{Amount}")]
public class Expense : IReturn<ExpenseResponse>
{
    public double Amount { get; set;
}
    
public class ExpenseResponse
{
    public double Amount { get; set; }
    public double Total { get; set; }
    public String Status { get; set; }
    public int WithdrawalsAmount { get; set; }
}

This change allows the usage of the client by following notation:

var response = jsonServiceClient.Post(new Expense { Amount = 500 });

Final Updates for the Client

The last change I want to make is to loop the user input, so that we can test the session mechanism in our console application. The following snippet waits for user input, as long as this input is a valid integer. If not, it breaks and the program terminates.

JsonServiceClient jsonServiceClient = new JsonServiceClient("http://localhost:61401");
int userInput;
while(Int32.TryParse(Console.ReadLine(), out userInput)) {
    var response = jsonServiceClient.Post(new Expense { Amount = userInput });
    Console.WriteLine(String.Format("Status: {0} - Withdrawals: {1} (Total: {2}, {3} Withdrawals)", response.Status, response.Amount, response.Total, response.WithdrawalsAmount));
}

The program does not contain any logic yet, so you can mess with it in different places. However, this basic example shows how easy it is to set up the C#-Client for ServiceStack and how to use it. In the next part, we will cover the basics of authentication and authorization, which allows us to increase our services security.