Author Archives: Berend de Jong

Remove obsolete nuget package references

To get rid of deprecated nuget packages in your solution follow the procedure below.

In Visual Studio first manage the nuget packages for your project (or solution) by right clicking the project in the solution explorer and choose Manage NuGet Packages…

Then the deprecated packages will show up in the list:

To remove those packages you have to remove them from the project file (or do an uninstall with the nuget package manager). I prefer to do this in the project file. So open the project file and remove the package entry (marked lines in the image below).

Now you have to add the FrameworkReference item to the project file. See the project file below and checkout the marked lines.

Check also this link for a more verbose explanation.

Share

GIT – remove unused branches

If you have some branche son your remote repository that are no longer in use you can delete them by following the steps below (make sure no one is updating these branches anymore).

First list the remote branches defined in your local repository

git branch -r

Now delete the branch with name Refactored (casesensitive) from origin (remote)

git push origin --deleted Refactored

Now to update the branches for a repository at another location (deleting stale branches) execute the command:

git fetch origin --prune

The local branches will be synced with the remote branches

Share

LetsEncrypt certificate renewal behind proxy

When deploying a .NET Core website on your domain, you likely utilize a reverse proxy to route traffic from ports 443 and 80 to your Kestrel web server. The configuration for this in Apache is as follows.

The line ProxyPass /.well-known/acme-challenge ! is included to ensure that Let’s Encrypt can successfully renew the certificate.

The other ProxyPass lines are for blazor to connect to the server.

ProxyRequests On
ProxyPreserveHost On
ProxyPass /.well-known/acme-challenge !
ProxyPassMatch ^/_blazor/(.*) http://0.0.0.0:5003/_blazor/$1
ProxyPass /_blazor ws://localhost:5003/_blazor
ProxyPass / http://0.0.0.0:5001/
ProxyPassReverse / http://0.0.0.0:5001/

Share

Ubuntu journalctl

If you want to view the log for a systemd service you can use the journalctl command. Basic Log Viewing: To view the logs for your prog-app service, you can use the following command:

sudo journalctl -u service-app

Tail Logs: If you want to follow the log in real-time, as new entries are added, use the -f flag:

sudo journalctl -fu service-app

Filter by Time: If you’re interested in logs from a specific time period, you can use --since and --until options. For example:

sudo journalctl -u service-app --since "2023-11-27" --until "2023-11-28"

Viewing the Most Recent Entries: To see the most recent entries, you can combine journalctl with other commands like tail. For example:

sudo journalctl -u service-app | tail -n 20
Share

Mollie Payments with C# / ASP.NET MVC Net Core

This post describes how to implement Mollie payments in your ASP.NET MVC Web application.

Begin by setting up an account at my.mollie.com. Ensure that you fully complete the registration process, which includes adding at least one payment method.

Following this, launch Visual Studio (or Visual Studio Code) and create a new MVC web application. The next step is to integrate the Mollie API. Do this by adding the NuGet package ‘Mollie.Api‘. As of the writing of this post, the current version is 3.3.0.

Continue reading
Share

LetsEncrypt request certificate error

Invalid host in redirect target “subdomain.domain.io.well-known”

When you get this error while requesting a new certificate you probably have a wrong redirect statement in your apache configuration.

The “redirect permanent” in the port 80 section should end with a / (or remove this entry while requesting a new certificate)

Share

Multilangual MVC application

Create a new ASP.Net MVC application

Add a Resources folder and add two files with this folder:
Views.Home.Index.en.resx
Views.Home.Index.nl.resx

Add an entry WelcomeText to both files. With a dutch value in the nl.resx file and an english value in the en.resx file.

Now update your startup.cs to support multiple languages. Edit your Program.cs in the root of the project file. Add this code right before var app = builder.Build();

// Add services to the container.
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddControllersWithViews()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("nl") };
    options.DefaultRequestCulture = new RequestCulture("en");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
});

And this code right before app.Run();

var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("nl") };
var localizationOptions = new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture("en"),
    SupportedCultures = supportedCultures,
    SupportedUICultures = supportedCultures
};

app.UseRequestLocalization(localizationOptions);

That’s it. Now you can switch between languages by adding ?culture=en or ?culture-nl to your url.

Share

LangChain – Create Chroma vector database

See also the LangChain cookbook.

Below is an example of creating a Chroma vector database using a TextSplitter with a simple text string.

from dotenv import load_dotenv
from langchain.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings

load_dotenv()

# https://platform.openai.com/docs/guides/embeddings/use-cases
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=10,  # default: 4000
    chunk_overlap=2  # default: 200
)

texts = text_splitter.create_documents(
    texts=['Often times your document is too long (like a book) for your LLM. You need to split it up into chunks. Text splitters help with this.'])

vectordb = Chroma.from_documents(
    documents=texts, embedding=embeddings, persist_directory="./dbtest")

You can also include PDF documents in your Chroma database. See the code below.

import os
from dotenv import load_dotenv
from langchain.vectorstores import Chroma
from langchain.document_loaders import DirectoryLoader
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings

load_dotenv()

if not any(file.endswith('.pdf') for file in os.listdir('.')):
    exit(1)

# https://platform.openai.com/docs/guides/embeddings/use-cases
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=2000,  # default: 4000
    chunk_overlap=100  # default: 200
)

loader = DirectoryLoader(".", glob='./*.pdf', loader_cls=PyPDFLoader)
documents = loader.load()

texts = text_splitter.split_documents(documents)

vectordb = Chroma.from_documents(
    documents=texts, embedding=embeddings, persist_directory="./dbtest")
Share