Trust the ASP.NET Core HTTPS development certificate on Fedora

sudo dnf install nss-tools

Setup Firefox

echo 'pref("general.config.filename", "firefox.cfg");
pref("general.config.obscure_value", 0);' > ./autoconfig.js

echo '//Enable policies.json
lockPref("browser.policies.perUserDir", false);' > firefox.cfg

echo "{
    \"policies\": {
        \"Certificates\": {
            \"Install\": [
            	\"aspnetcore-localhost-https.crt\"
            ]
        }
    }
}" > policies.json

dotnet dev-certs https -ep localhost.crt --format PEM

sudo mv autoconfig.js /usr/lib64/firefox/
sudo mv firefox.cfg /usr/lib64/firefox/
sudo mv policies.json /usr/lib64/firefox/distribution/
mkdir -p ~/.mozilla/certificates
cp localhost.crt ~/.mozilla/certificates/aspnetcore-localhost-https.crt

Trust Edge/Chrome

certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i ./localhost.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n localhost -i ./localhost.crt

Trust dotnet-to-dotnet

sudo cp localhost.crt /etc/pki/tls/certs/aspnetcore-localhost-https.pem
sudo update-ca-trust

Cleanup

rm localhost.crt

References
https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-6.0&tabs=visual-studio#trust-https-certificate-on-linux
https://github.com/dotnet/aspnetcore/issues/32842
https://github.com/dotnet/aspnetcore/issues/32361

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

Return JSON Data from ASP.NET MVC Controllers

Send JSON Content welcome note based on user type

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Web.Mvc;  
using System.Web.Script.Serialization;  
using JsonResultDemo.Models;  
  
namespace JsonResultDemo.Controllers  
{  
    public class JsonDemoController : Controller  
    {  
        #region ActionControllers  
  
        /// <summary>  
        /// Welcome Note Message  
        /// </summary>  
        /// <returns>In a Json Format</returns>  
        public JsonResult WelcomeNote()  
        {  
            bool isAdmin = false;  
            //TODO: Check the user if it is admin or normal user, (true-Admin, false- Normal user)  
            string output = isAdmin ? "Welcome to the Admin User" : "Welcome to the User";  
  
            return Json(output, JsonRequestBehavior.AllowGet);  
        }  
     }  
}

Get the list of users in JSON Format

/// <summary>  
/// Update the user details  
/// </summary>  
/// <param name="usersJson">users list in JSON Format</param>  
/// <returns></returns>  
[HttpPost]  
public JsonResult UpdateUsersDetail(string usersJson)  
{  
    var js = new JavaScriptSerializer();  
    UserModel[] user = js.Deserialize<UserModel[]>(usersJson);  
  
    //TODO: user now contains the details, you can do required operations  
    return Json("User Details are updated");  
}

References
https://www.c-sharpcorner.com/UploadFile/2ed7ae/jsonresult-type-in-mvc/
https://stackoverflow.com/questions/227624/asp-net-mvc-controller-actions-that-return-json-or-partial-html