Category Archives: C#

c# async in constructors

In C#, constructors cannot be declared as async because they are special methods used for object initialization and cannot be awaited. However, you can use an asynchronous factory method or an initialization method to perform asynchronous operations during object creation. Here’s an example:

public class MyClass
{
    private MyClass()
    {
        // Private constructor to enforce the usage of factory method
    }

    public static async Task<MyClass> CreateAsync()
    {
        var instance = new MyClass();
        await instance.InitializeAsync();
        return instance;
    }

    private async Task InitializeAsync()
    {
        // Perform asynchronous initialization tasks here
        await Task.Delay(1000); // Example asynchronous operation
    }
}

In the above example, the constructor for MyClass is marked as private to enforce the usage of the CreateAsync factory method. The CreateAsync method creates an instance of MyClass, calls the private constructor, and then asynchronously initializes the object by calling the InitializeAsync method. You can perform any necessary asynchronous operations within the InitializeAsync method.

To create an instance of MyClass, you would use the CreateAsync method as follows:

var myObject = await MyClass.CreateAsync();

By using this approach, you can achieve asynchronous behavior during object construction in C#.

Share

Bootstrap Image dropdown

Below is a bootstrap fragment to setup a dropdown input with images.

<html>

<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
        .img-dropdown {
            display: inline-block;
            vertical-align: middle;
            margin-right: 10px;
            width: 20px;
            height:20px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="row">
            <div class="col">
                <div style="float:left">
                    <div class="dropdown">
                        <button class="btn btn-secondary" type="button" id="dropdownMenuButton"
                            data-bs-toggle="dropdown" aria-expanded="false">
                            <div id="languageButtonText">??</div>
                        </button>
                        <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton" id="ulLanguages">
                            <li>
                                <a class="dropdown-item" href="#" data-value="DE">
                                    <img src="img/de.svg" alt="Image 1" class="img-dropdown">
                                    German
                                </a>
                            </li>
                            <li>
                                <a class="dropdown-item" href="#" data-value="FR">
                                    <img src="img/fr.svg" alt="Image 2" class="img-dropdown">
                                    French
                                </a>
                            </li>
                            <li>
                                <a class="dropdown-item" href="#" data-value="GB">
                                    <img src="img/gb.svg" alt="Image 3" class="img-dropdown">
                                    English
                                </a>
                            </li>
                            <li>
                                <a class="dropdown-item" href="#" data-value="NL">
                                    <img src="img/nl.svg" alt="Image 4" class="img-dropdown">
                                    Dutch
                                </a>
                            </li>
                            <li>
                                <a class="dropdown-item" href="#" data-value="Frisian">
                                    <img src="img/frisian.svg" alt="Image 5" class="img-dropdown">
                                    Frisian
                                </a>
                            </li>
                        </ul>
                    </div>
                </div>
                <div style="float:left">
                    <div id="selected-image" style="align-items: center; display:flex;margin-left:5px"></div>
                </div>
            </div>
        </div>
    </div>
</body>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"
    integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
    crossorigin="anonymous"></script>
<script>
    $(document).ready(function () {

        // When a dropdown item is clicked
        $('.dropdown-item').click(function () {
            var lang = $(this).data('value');
            var id = 'Language';
            $('#' + id).val(lang);

            // Get the image source of the clicked item
            var selectedImageSrc = $(this).find('img').attr('src');

            // Set the selected image in the div
            $('#selected-image').html('<img src="' + selectedImageSrc + '" alt="Selected Image" width="51">');
            $("#languageButtonText").html(lang);
        });

        $("#ulLanguages li a").filter("[data-value=" + "Frisian" + "]").trigger("click");

    });
</script>

</html>
Share

Add syntax highlighting to ASP.NET site

To enable syntax highlighting on your ASP.NET site follow the steps below:

  1. Goto prismjs.com and press the Download button.
  2. Add the next items to the default languages: C#, ASP.NET (C#), Bash + Shell + Shell, C#, Razor C# and SQL.
  3. Also add the plugin “line-numbers”.
  4. At the bottom of the page download the prims.js and prism.css files.

In the Shared/_Layout.cshtml add both the prism.js and prism.css file.

In the Index.cshtml view add some code to test it out

<div class="row">
    <div class="col line-numbers">
<pre><code class="language-csharp">public class HelloWorld
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");
    }
}
</code>
</pre>
</div>
    <div class="col">
        <pre>
<code class="language-sql">
SELECT * FROM AspNetUsers u
LEFT JOIN AspNetRols on r.Id = u.Id
WHERE ID = 1;
</code>
    </pre>
    </div>
</div>

The resulting page will look like this

Share

Use an in-memory database in EF Core 7

This is the minimal setup to use an in-memory datase in EF Core 7 with a Console program. C# solution can be found here.

After creating your C# Net Core 7 Console App project add two nuget packages to the project:

Install Package Microsoft.EntityFrameworkCore
Install Package Microsoft.EntityFrameworkCore.InMemory

Next add a class Person to your console project

internal class Person
{
    public int Id { get; set; }

    [Required]
    public string FirstName { get; set; } = string.Empty;
    [Required]
    public string LastName { get; set; } = string.Empty;
}

Next add your database context class, remember to derive it from DbContext.

internal class MyDatabaseContext : DbContext
{
    public DbSet<Person> Persons { get; set; }

    public MyDatabaseContext(DbContextOptions<MyDatabaseContext> options) : base(options)
    {
    }
}

Now we can use our database context in the main program as shown below

MyDatabaseContext db = new MyDatabaseContext(
    new DbContextOptionsBuilder<MyDatabaseContext>().UseInMemoryDatabase("TEST").Options);

db.Persons.Add(new Person() {  FirstName = "Berend", LastName = "de Jong"});
db.SaveChanges();
db.Persons.ForEachAsync((person) => Console.WriteLine($"{person.Id}\t{person.FirstName}\t{person.LastName}"));

As an alternative you can use a parameterless constructor and override the OnConfiguring method of the DbContext class to configure your connection.

Remove the options parameter from the constructor and the call to the base constructor. Next override the OnConfiguring method of the DbContext as shown below.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseInMemoryDatabase("TEST");
}
Share

Using a test collection with test fixture in 5 steps

Sometimes you need some generic setup code for your tests. As you might know the constructor is called for every test Fact in your test class. For setup code that only needs to run once you can define a Test Fixture class. In the steps below is outlined how this can be accomplished in C#.

Define a collection definition by using the CollectionDefinition attribute

namespace XUnitTestProject
{
    using Xunit;

    [CollectionDefinition("MyTestCollection")]
    public class MyTestCollectionDefinition : ICollectionFixture<MyTestFixture>
    {
    }
}

Create the MyTextFixture class

public class EWCTestFixture
{
    public MyDbContext Context;

    public MyTestFixture()
    {
        MySqlConnection Connection = new MySqlConnection(connectionString);

        Context = new MyDbContext(userService, new DbContextOptionsBuilder<MyDbContext>()
            .UseMySql(Connection, ServerVersion.AutoDetect(Connection.ConnectionString)).Options);
        Context.Database.EnsureCreated();
        Connection.Open();
    }
}

Create a test collection for this fixture by using the Collection attribute (be sure you use the same name as used by the CollectionDefinition). The test framework takes care of injecting the MyTestFixture into the constructor.

[Collection("MyTestCollection")]
public class MyDbContextShould : IDisposable
{
    private MyTestFixture Fixture;

    private IDbContextTransaction transaction { get; }

    public MyDbContextShould(MyTestFixture fixture)
    {
        this.Fixture = fixture;
        this.transaction = Fixture.Context.Database.BeginTransaction();
    }
}

Use the test fixture in your test facts where needed.

[Fact]
public void MyObjectIsStoreInheDatabase()
{
    Fixture.Context.MyObjects.Add(new MyObject());
    Fixture.Context.SaveChanges();
    Assert.Single(Fixture.Context.MyObjects);
}

Finally define a dispose object to dispose the transaction created in the constructor.

public void Dispose()
{
    this.transaction.Dispose();
}
Share

Determine domain behind proxy in ASP.NET MVC controller

Sometimes you need to know the domain on which your app is running. If you are behind a proxy there is not a straightforward way to determine this.

To get the “real” domain name for your app check the “X-Forwarded-Host” HTTP header and use this as your host name when, for example, sending links in emails to your app.

First step is to get the host name:

public static string GetForwardedHost(HttpRequest Request)
{
   string host = Request.Headers["X-Forwarded-Host"];
   if (host == null)
   {
      host = Request.Host.ToString();
   }
   return host;
}

Next when you assemble a link for in example an email you want so sent use the code below

var host = Utils.GetForwardedHost(Request);

var callbackUrl = Url.Page(
                    "/Account/ResetPassword",
                    pageHandler: null,
                    values: new { area = "Identity", code },
                    protocol: Request.Scheme, host : host);

this.SendEmail(Input.Email, "Reset Password", $"Please reset your password by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
Share

Cross-Site HTTP Requests

A request for data from a different server (other than the requesting page), are called cross-site HTTP requests.

Cross-site requests are common on the web. Many pages load CSS, images, and scripts from different servers.

In modern browsers, cross-site HTTP requests from scripts are restricted to same site for security reasons.

To allow Cross-site requests to your api, add the following package

Microsoft.AspNetCore.Cors

In program.cs add the line

builder.Services.AddCors();

Add add the next line after your app is build (var app = builder.Build())

app.UseCors(<br>options => options.WithOrigins("https://localhost:7219").AllowAnyMethod());

Share

Synology Docker MariaDb / .NET Core 6 / Homewizzard Electrical meter reading

HomeWizard P1 meter

Recently I came across a small device that can be connected to the Smart Energy Meter as it is used in the Netherlands, among other places:

HomeWizard.nl

This small device is connected to the P1 port of the smart meter. The HomeWizzard is then connected to the WiFi network.

The HomeWizzard device publishes a REST api at this endpoint https://[your-homewizzard-device-ip]/api/v1/data.

Continue reading
Share