Create Indexes in MongoDB via .NET

static async Task CreateIndexAsync()
{
    var client = new MongoClient();
    var database = client.GetDatabase("HamsterSchool");
    var collection = database.GetCollection<Hamster>("Hamsters");
    var indexKeysDefinition = Builders<Hamster>.IndexKeys.Ascending(hamster => hamster.Name);
    await collection.Indexes.CreateOneAsync(new CreateIndexModel<Hamster>(indexKeysDefinition));
}

References
https://stackoverflow.com/questions/17807577/how-to-create-indexes-in-mongodb-via-net

Setting up Serilog in .NET 6 for ASP.NET

dotnet add package Serilog.AspNetCore

Select Providers:

https://github.com/serilog/serilog/wiki/Provided-Sinks

Program.cs

builder.Host.UseSerilog((ctx, lc) => lc
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day)
    .WriteTo.MongoDBBson("mongodb://localhost/interfaces","logs"));

Finally, clean up by removing the remaining configuration for the default logger, including the "Logging" section from appsettings.*.json files

References
https://github.com/serilog/serilog-aspnetcore
https://blog.datalust.co/using-serilog-in-net-6/
https://github.com/serilog/serilog-sinks-console
https://github.com/serilog/serilog-sinks-file
https://github.com/serilog/serilog-sinks-mongodb
https://github.com/saleem-mirza/serilog-sinks-sqlite

Response Caching in ASP.NET Core

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching();

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();
//Near the start
app.UseResponseCompression();

//ensure response compression is added before static files

app.UseStaticFiles();

References
https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-6.0
https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-6.0
https://stackoverflow.com/questions/46832723/net-core-response-compression-middleware-for-static-files

Response Compression in ASP.NET Core

The following code shows how to enable the Response Compression Middleware for default MIME types and compression providers (Brotli and Gzip):

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCompression();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCompression();
    }
}

Customize

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

References
https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-6.0

Use the Angular project template with ASP.NET Core

Create a new app

dotnet new angular -o my-new-app
cd my-new-app

Add pages, images, styles, modules, etc.

The ClientApp directory contains a standard Angular CLI app

Run ng commands

remove package-lock.json then :

cd ClientApp
npm install

Install npm packages

cd ClientApp
npm install --save <package_name>

Run “ng serve” independently

cd ClientApp
npm start

Use npm start to launch the Angular CLI development server, not ng serve, so that the configuration in package.json is respected. To pass additional parameters to the Angular CLI server, add them to the relevant scripts line in your package.json file.

In your Startup class, replace the spa.UseAngularCliServer invocation with the following:

spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");

References
https://docs.microsoft.com/en-us/aspnet/core/client-side/spa/angular?view=aspnetcore-6.0&tabs=visual-studio

Worker Services in .NET

A worker service is a .NET project built using a template which supplies a few useful features that turn a regular console application into something more powerful. A worker service runs on top of the concept of a host, which maintains the lifetime of the application. The host also makes available some familiar features, such as dependency injection, logging and configuration.

Worker services will generally be long-running services, performing some regularly occurring workload.

There are numerous reasons for creating long-running services such as:

  • Processing CPU intensive data.
  • Queuing work items in the background.
  • Performing a time-based operation on a schedule.

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Worker.cs

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;

    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }
}

Register an IHostedService

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
            services.AddHostedService<Worker>();
        });

References
https://docs.microsoft.com/en-us/dotnet/core/extensions/workers
https://www.stevejgordon.co.uk/what-are-dotnet-worker-services
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio

Call a Web API from ASP.NET Core Blazor Server

In Program.cs:

builder.Services.AddHttpClient();

Read String using GET method

@page "/"
@inject IHttpClientFactory ClientFactory

<PageTitle>Index</PageTitle>

<button @onclick="Button_Clicked">Call API</button>

@code {

    private async Task Button_Clicked()
    {
    // read string using GET method
        var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5055/hello-world");
        var client = ClientFactory.CreateClient();
        var response = await client.SendAsync(request);

        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine(await response.Content.ReadAsStringAsync());
        }
    }

}

Send and Read JSON using POST method

private async Task Button2_Clicked()
{
// send and read json using POST method
    var url = "http://localhost:5055/hello2";
    var person = new Person() {FirstName = "Mahmood", LastName = "Ramzani"};
    var json = JsonSerializer.Serialize(person);
    var data = new StringContent(json, Encoding.UTF8, "application/json");
    var client = ClientFactory.CreateClient();
    var response = await client.PostAsync(url, data);

    if (response.IsSuccessStatusCode)
    {
        Console.WriteLine(await response.Content.ReadAsStringAsync());
    }
}

 

References
https://docs.microsoft.com/en-us/aspnet/core/blazor/call-web-api?view=aspnetcore-6.0&pivots=server

JSON Parameter in ASP.NET MVC using [FromBody]

To force Web API to read a simple type from the request body, add the [FromBody] attribute to the parameter:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
[Route("hello2"), HttpPost]
public JsonResult Hello2([FromBody] Person person)
{
    string output = $@"Hello {person.FirstName} {person.LastName}";
    return Json(output);
}

When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is “application/json” and the request body is a raw JSON string (not a JSON object).

References
https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api