dotnet-sdk/samples/AspNetCore/RoutingSample
Shalabh Mohan Shrivastava 5b8a426e7d
Add support in dotnet client sdk to support multi state store support (#207)
* Including state Store name in the APIs to support multi state store scenario in SDK

* correcting the typo in the comment.

* Respective Changes to the tests

* Changes in StateAttribute and Binder classes to support state store name

* Changes in StateEntryModelBinderTests

* StoreName changes in the Integration test app

* fixing build issues

* Fixing integration tests

* Addressing review comments.

* Addressing review comments

* Updating samples to use correct state store name as generated by dapr cli.

Co-authored-by: Aman Bhardwaj <amanbha@users.noreply.github.com>
2020-02-06 09:06:21 -08:00
..
Properties ADding launchsettings.json to user port for local launch (#111) 2019-10-17 17:57:48 -07:00
Account.cs moving aspnetcore sample to its own folder (#95) 2019-10-13 17:37:32 -07:00
Program.cs Removed unused usings (#122) 2019-10-21 09:53:55 -07:00
Readme.md Using 127.0.0.1 instead of localhost. (#214) 2020-02-05 12:32:41 -08:00
RoutingSample.csproj Build for net core 3.1 (#189) 2019-12-16 09:31:25 -08:00
Startup.cs Add support in dotnet client sdk to support multi state store support (#207) 2020-02-06 09:06:21 -08:00
Transaction.cs moving aspnetcore sample to its own folder (#95) 2019-10-13 17:37:32 -07:00
appsettings.json moving aspnetcore sample to its own folder (#95) 2019-10-13 17:37:32 -07:00

Readme.md

ASP.NET Core Routing Sample

This sample shows using Dapr with ASP.NET Core routing. This application is a simple and not-so-secure banking application. The application uses the Dapr state-store for its data storage.

It exposes the following endpoints over HTTP:

  • GET /{id}: Get the balance for the account specified by id
  • POST /deposit: Accepts a JSON payload to deposit money to an account
  • POST /withdraw: Accepts a JSON payload to withdraw money from an account

The application also registers for pub-sub with the deposit and withdraw topics.

Running the Sample

To run the sample locally run this comment in this directory:

dapr run --app-id routing --app-port 5000 dotnet run

The application will listen on port 5000 for HTTP.

Examples

Deposit Money

On Linux, MacOS:

curl -X POST http://127.0.0.1:5000/deposit \
       -H 'Content-Type: application/json' \
       -d '{ "id": "17", "amount": 12 }'

On Windows:

curl -X POST http://127.0.0.1:5000/deposit -H "Content-Type: application/json" -d "{ \"id\": \"17\", \"amount\": 12 }"

Output:

 {"id":"17","balance":12}

Withdraw Money On Linux, MacOS:

curl -X POST http://127.0.0.1:5000/withdraw \
       -H 'Content-Type: application/json' \
       -d '{ "id": "17", "amount": 10 }'

On Windows:

curl -X POST http://127.0.0.1:5000/withdraw -H "Content-Type: application/json" -d "{ \"id\": \"17\", \"amount\": 10 }"

Output:

{"id":"17","balance":2}

Get Balance

curl http://127.0.0.1:5000/17

Output:

{"id":"17","balance":2}

Withdraw Money (pubsub) Publish events using Dapr cli: On Linux, MacOS:

dapr publish -t withdraw -p '{"id": "17", "amount": 15 }'

On Windows:

dapr publish -t withdraw -p "{\"id\": \"17\", \"amount\": 15 }"

Deposit Money (pubsub) Publish events using Dapr cli: On Linux, MacOS:

dapr publish -t deposit -p '{"id": "17", "amount": 15 }'

On Windows:

dapr publish -t deposit -p "{\"id\": \"17\", \"amount\": 15 }"

Code Samples

All of the interesting code in this sample is in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
   services.AddDaprClient();

   ...
}

AddDaprClient() registers the StateClient service with the dependency injection container. This service can be used to interact with the Dapr state-store.


app.UseCloudEvents();

UseCloudEvents() registers the Cloud Events middleware in the request processing pipeline. This middleware will unwrap requests with Content-Type application/cloudevents+json so that application code can access the event payload in the request body directly. This is recommended when using pub/sub unless you have a need to process the event metadata yourself.


app.UseEndpoints(endpoints =>
{
    endpoints.MapSubscribeHandler();

    endpoints.MapGet("{id}", Balance);
    endpoints.MapPost("deposit", Deposit).WithTopic("deposit");
    endpoints.MapPost("withdraw", Withdraw).WithTopic("withdraw");
});

MapSubscribeHandler() registers an endpoint that will be called by the Dapr runtime to register for pub-sub topics. This is is not needed unless using pub-sub.

MapGet(...) and MapPost(...) are provided by ASP.NET Core routing - these are used to setup endpoints to handle HTTP requests.

WithTopic(...) associates an endpoint with a pub-sub topic.


async Task Balance(HttpContext context)
{
    var client = context.RequestServices.GetRequiredService<StateClient>();

    var id = (string)context.Request.RouteValues["id"];
    var account = await client.GetStateAsync<Account>(id);
    if (account == null)
    {
        context.Response.StatusCode = 404;
        return;
    }

    context.Response.ContentType = "application/json";
    await JsonSerializer.SerializeAsync(context.Response.Body, account, serializerOptions);
}

Here GetRequiredService<StateClient>() is used to retrieve the StateClient from the service provider.

client.GetStateAsync<Account>(id) is used to retrieve an Account object from that state-store using the key in the variable id. The Account object stored in the state-store as JSON. If no entry is found for the specified key, then null will be returned.


await client.SaveStateAsync(transaction.Id, account);

SaveStateAsync(...) is used to save data to the state-store.