CSharp Rest API: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 18: Line 18:
dotnet dev-certs https --clean
dotnet dev-certs https --clean
dotnet dev-certs https --check --trust
dotnet dev-certs https --check --trust
</syntaxhighlight>
==Dependency Inject DI==
This just points out how to inject one service into another. With the example below we only use the Repository once so creating it as its own system is a bit silly. Anyway this is how to do it.
<syntaxhighlight lang="cs">
builder.Services.AddSingleton<IRepository>(provider =>
{
    BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
    BsonSerializer.RegisterSerializer(new DateTimeOffsetSerializer(BsonType.String));
    var mongoDbSettings = builder.Configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>();
    var client = new MongoClient(mongoDbSettings.ConnectionString);
    return new MongoDBItemsRepository(client);
});
builder.Services.AddSingleton<IItemService>(provider => new ItemService(provider.GetRequiredService<IRepository>()));
</syntaxhighlight>
</syntaxhighlight>
==Express C# Style==
==Express C# Style==
Line 60: Line 75:
app.Run();
app.Run();
</syntaxhighlight>
</syntaxhighlight>
==C# Extensions==
==C# Extensions==
I never used this a lot in the first 7 years of C#. For the last 3 it was all the rage. Basically they are functions which take this as the first argument
I never used this a lot in the first 7 years of C#. For the last 3 it was all the rage. Basically they are functions which take this as the first argument

Revision as of 23:16, 8 November 2024

Introduction

This is a quick refresher for C# Rest API

Installation

I am now on SDK 8.0 and found the following issues

Use Apt not Snap

Using snap will mean your SDK cannot be found

sudo apt-get install dotnet-sdk-8.0

Create new Project

This is painless and can be done with

dotnet new webapi -n Catalog

Setting up Certificates

The next thing is run the project with F5. This warns you that you are not https. You fix this with the commands below but make sure you restart chrome

dotnet dev-certs https --clean
dotnet dev-certs https --check --trust

Dependency Inject DI

This just points out how to inject one service into another. With the example below we only use the Repository once so creating it as its own system is a bit silly. Anyway this is how to do it.

builder.Services.AddSingleton<IRepository>(provider =>
{
    BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
    BsonSerializer.RegisterSerializer(new DateTimeOffsetSerializer(BsonType.String));

    var mongoDbSettings = builder.Configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>();
    var client = new MongoClient(mongoDbSettings.ConnectionString);
    return new MongoDBItemsRepository(client);
});

builder.Services.AddSingleton<IItemService>(provider => new ItemService(provider.GetRequiredService<IRepository>()));

Express C# Style

This is an example of using the minimal api from Microsoft. The import thing is the minimal API is a new approach to reduce the code required to get going. The AddSingleton is a way to use Dependency Injection. I found the errors unreadable from the framework but maybe used to working at a lower level. Quite easy to see how to get going

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IItemService>(provider => new ItemService(new InMemItemsRepository()));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

app.UseStatusCodePages(async statusCodeContext
    => await Results.Problem(statusCode: statusCodeContext.HttpContext.Response.StatusCode)
        .ExecuteAsync(statusCodeContext.HttpContext));

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.MapGet("/items", (IItemService itemService) =>
    TypedResults.Ok(itemService.GetItems()))
    .WithName("GetItems")
    .WithOpenApi();


app.MapGet("/items/{id}", Results<Ok<ItemDto>, NotFound> (IItemService itemService, Guid id) =>
        itemService.GetItem(id) is { } itemDto
            ? TypedResults.Ok(itemDto)
            : TypedResults.NotFound()
    )
    .WithName("GetItemById")
    .WithOpenApi();


app.Run();

C# Extensions

I never used this a lot in the first 7 years of C#. For the last 3 it was all the rage. Basically they are functions which take this as the first argument

namespace Catalog.Extensions;

using Catalog.Dtos;
using Catalog.Entities;

public static class Extensions
{
    public static ItemDto AsDto(this Item item)
    {
        return new ItemDto
        {
            Id = item.Id,
            Name = item.Name,
            Price = item.Price,
            CreatedDate = item.CreatedDate
        };
    }
}

So now you can do this

    public IEnumerable<ItemDto> GetItems()
    {
        var itemDtos = repository.GetItems().Select(item => item.AsDto());

        return itemDtos;
    }