diff --git a/_data/Sloader.json b/_data/Sloader.json index 101e551..e6d3c1d 100644 --- a/_data/Sloader.json +++ b/_data/Sloader.json @@ -1 +1 @@ -{"Data":{"Blog":{"FeedItems":[{"Title":"OpenAI API, LM Studio and Ollama","PublishedOn":"2024-09-17T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

I had the opportunity to attend the .NET User Group Dresden at the beginning of September for the exciting topic “Using Open Source LLMs” and learned a couple of things.

\n\n

How to choose an LLM?

\n\n

There are tons of LLMs (= Large Language Models) that can be used, but which one should we choose? There is no general answer to that - of course - but there is a Chatbot Arena Leaderboard, which measures the “cleverness” between those models. Be aware of the license of each model.

\n\n

There is also a HuggingChat, where you can pick some models and experiment with them.

\n\n

For your first steps on your local hardware: Phi3 does a good job and is not a huge model.

\n\n

LM Studio

\n\n

Ok, you have a model and an idea, but how to play with it on your local machine?

\n\n

The best tool for such a job is: LM Studio.

\n\n

The most interesting part was (and this was “new” to me), that you run those local models in an local, OpenAI compatible (!!!) server.

\n\n

\"x\"

\n\n

OpenAI Compatible server?!

\n\n

If you want to experiment with a lightweight model on your system and interact with it, then it is super handy, if you can use the standard OpenAI client and just run against your local “OpenAI”-like server.

\n\n

Just start the server, use the localhost endpoint and you can use a code like this:

\n\n
using OpenAI.Chat;\nusing System.ClientModel;\n\nChatClient client = new(model: \"model\", \"key\",\n        new OpenAI.OpenAIClientOptions()\n        { Endpoint = new Uri(\"http://localhost:1234/v1\") });\n\nChatCompletion chatCompletion = client.CompleteChat(\n    [\n        new UserChatMessage(\"Say 'this is a test.'\"),\n    ]);\n\nConsole.WriteLine(chatCompletion.Content[0].Text);\n
\n\n

The model and the key don’t seem to matter that much (or at least I worked on my machine). The localhost:1234 service is hosted by LM Studio on my machine. The actual model can be configured in LM Studio and there is a huge choice available.

\n\n

Even streaming is supported:

\n\n
AsyncCollectionResult<StreamingChatCompletionUpdate> updates\n    = client.CompleteChatStreamingAsync(\"Write a short story about a pirate.\");\n\nConsole.WriteLine($\"[ASSISTANT]:\");\nawait foreach (StreamingChatCompletionUpdate update in updates)\n{\n    foreach (ChatMessageContentPart updatePart in update.ContentUpdate)\n    {\n        Console.Write(updatePart.Text);\n    }\n}\n
\n\n

Ollama

\n\n

The obvious next question is: How can I run my own LLM on my own server? LM Studio works fine, but it’s just a development tool.

\n\n

One answer could be: Ollama, which can run large language models and has a compatibility to the OpenAI API.

\n\n

Is there an Ollama for .NET devs?

\n\n

Ollama looks cool, but I was hoping to find an “OpenAI compatible .NET facade”. I already played with LLamaSharp, but LLamaSharp doesn’t offer currently a WebApi, but there are some ideas around. \nMy friend Gregor Biswanger released OllamaApiFacade, which looks promising, but at least it doesn’t offer a real OpenAI compatible .NET facade, but maybe this will be added in the future.

\n\n

Acknowledgment

\n\n

Thanks to the .NET User Group for hosting the meetup, and a special thanks to my good friend Oliver Guhr, who was also the speaker!

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/09/17/openai-api-lmstudio-ollama/","RawContent":null,"Thumbnail":null},{"Title":"Entity Framework Core 8.0 Breaking Changes & SQL Compatibility Level","PublishedOn":"2024-09-08T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We recently switched from .NET 6 to .NET 8 and encountered the following Entity Framework Core error:

\n\n
Microsoft.Data.SqlClient.SqlException: 'Incorrect syntax near the keyword 'WITH'....\n
\n\n

The EF code uses the Contains method as shown below:

\n\n
var names = new[] { \"Blog1\", \"Blog2\" };\n\nvar blogs = await context.Blogs\n    .Where(b => names.Contains(b.Name))\n    .ToArrayAsync();\n
\n\n

Before .NET 8 this would result in the following Sql statement:

\n\n
SELECT [b].[Id], [b].[Name]\nFROM [Blogs] AS [b]\nWHERE [b].[Name] IN (N'Blog1', N'Blog2')\n
\n\n

… and with .NET 8 it uses the OPENJSON function, which is not supported on older versions like SQL Server 2014 or if the compatibility level is below 130 (!)

\n\n\n\n

The fix is “simple”

\n\n

Ensure you’re not using an unsupported SQL version and that the Compatibility Level is at least on level 130.

\n\n

If you can’t change the system, then you could also enforce the “old” behavior with a setting like this (not recommended, because it is slower!)

\n\n
...\n.UseSqlServer(@\"<CONNECTION STRING>\", o => o.UseCompatibilityLevel(120));\n
\n\n

How to make sure your database is on Compatibility Level 130?

\n\n

Run this statement to check the compatibility level:

\n\n
SELECT name, compatibility_level FROM sys.databases;\n
\n\n

We updated our test/dev SQL Server and then moved all databases to the latest version with this SQL statement:

\n\n
DECLARE @DBName NVARCHAR(255)\nDECLARE @SQL NVARCHAR(MAX)\n\n-- Cursor to loop through all databases\nDECLARE db_cursor CURSOR FOR\nSELECT name\nFROM sys.databases\nWHERE name NOT IN ('master', 'tempdb', 'model', 'msdb') -- Exclude system databases\n\nOPEN db_cursor\nFETCH NEXT FROM db_cursor INTO @DBName\n\nWHILE @@FETCH_STATUS = 0\nBEGIN\n    -- Construct the ALTER DATABASE command\n    SET @SQL = 'ALTER DATABASE [' + @DBName + '] SET COMPATIBILITY_LEVEL = 150;'\n    EXEC sp_executesql @SQL\n\n    FETCH NEXT FROM db_cursor INTO @DBName\nEND\n\nCLOSE db_cursor\nDEALLOCATE db_cursor\n
\n\n

Check EF Core Breaking Changes

\n\n

There are other breaking changes, but only the first one affected us: Breaking Changes

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/09/08/ef-core-8-breaking-changes-and-sql-compatibility-level/","RawContent":null,"Thumbnail":null},{"Title":"Connection Resiliency for Entity Framework Core and SqlClient","PublishedOn":"2024-09-02T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

If you work with SQL Azure you might find this familiar:

\n\n
\n

Unexpected exception occurred: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding ‘EnableRetryOnFailure’ to the ‘UseSqlServer’ call.

\n
\n\n

EF Core Resiliency

\n\n

The above error already shows a very simple attempt to “stabilize” your application. If you are using Entity Framework Core, this could look like this:

\n\n
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)\n{\n    optionsBuilder\n        .UseSqlServer(\n            @\"Server=(localdb)\\mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0\",\n            options => options.EnableRetryOnFailure());\n}\n
\n\n

The EnableRetryOnFailure-Method has a couple of options, like a retry count or the retry delay.

\n\n

If you don’t use the UseSqlServer-method to configure your context, there are other ways to enable this behavior: See Microsoft Docs

\n\n

Microsoft.Data.SqlClient - Retry Provider

\n\n

If you use the “plain” Microsoft.Data.SqlClient NuGet Package to connect to your database have a look at Retry Logic Providers

\n\n

A basic implementation would look like this:

\n\n
// Define the retry logic parameters\nvar options = new SqlRetryLogicOption()\n{\n    // Tries 5 times before throwing an exception\n    NumberOfTries = 5,\n    // Preferred gap time to delay before retry\n    DeltaTime = TimeSpan.FromSeconds(1),\n    // Maximum gap time for each delay time before retry\n    MaxTimeInterval = TimeSpan.FromSeconds(20)\n};\n\n// Create a retry logic provider\nSqlRetryLogicBaseProvider provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);\n\n// Assumes that connection is a valid SqlConnection object \n// Set the retry logic provider on the connection instance\nconnection.RetryLogicProvider = provider;\n// Establishing the connection will retry if a transient failure occurs.\nconnection.Open();\n
\n\n

You can set a RetryLogicProvider on a Connection and on a SqlCommand.

\n\n

Some more links and tips

\n\n

These two options seem to be the “low-level-entry-points”.\nOf course could you wrap each action with a library like Polly.

\n\n

During my research I found a good overview: Implementing Resilient Applications.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/09/02/connection-resiliency-for-ef-core-and-sql-data/","RawContent":null,"Thumbnail":null},{"Title":"UrlEncode the Space Character","PublishedOn":"2024-08-20T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

This might seem trivial, but last week I noticed that the HttpUtility.UrlEncode(string) encodes a space ` ` into +, whereas the JavaScript encodeURI(string) method encodes a space as %20.\nThis brings up the question:

\n\n

Why?

\n\n

It seems that in the early specifications, a space was encoded into a +, see this Wikipedia entry:

\n\n
\n

When data that has been entered into HTML forms is submitted, the form field names and values are encoded and sent to the server in an HTTP request message using method GET or POST, or, historically, via email.[3] The encoding used by default is based on an early version of the general URI percent-encoding rules,[4] with a number of modifications such as newline normalization and replacing spaces with + instead of %20. The media type of data encoded this way is application/x-www-form-urlencoded, and it is currently defined in the HTML and XForms specifications. In addition, the CGI specification contains rules for how web servers decode data of this type and make it available to applications.

\n
\n\n

This convention has persisted to this day. For instance, when you search something on Google or Bing with a space in the query, the space is encoded as a +.

\n\n

There seems to be some rules however, e.g. it is only “allowed” in the query string or as form parameters.

\n\n

I found the question & answers on StackOverflow quite informative, and this answer summarizes it well enough for me:

\n\n
| standard      | +   | %20 |\n|---------------+-----+-----|\n| URL           | no  | yes |\n| query string  | yes | yes |\n| form params   | yes | no  |\n| mailto query  | no  | yes |\n
\n\n

What about .NET?

\n\n

If you want to always encode spaces as %20, use the UrlPathEncode method, see here.

\n\n
\n

You can encode a URL using with the UrlEncode method or the UrlPathEncode method. However, the methods return different results. The UrlEncode method converts each space character to a plus character (+). The UrlPathEncode method converts each space character into the string “%20”, which represents a space in hexadecimal notation. Use the UrlPathEncode method when you encode the path portion of a URL in order to guarantee a consistent decoded URL, regardless of which platform or browser performs the decoding.

\n
\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/08/20/urlencoding-the-space-char/","RawContent":null,"Thumbnail":null},{"Title":"dsregcmd, WAM and 'Connected to Windows'-Accounts","PublishedOn":"2024-08-06T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

I was researching if it is possible to have a “real” single-sign-on experience with Azure AD/Entra ID and third-party desktop applications and I stumbled across a few things during my trip.

\n\n

“Real” SSO?

\n\n

There are a bunch of definitions out there about SSO.\nMost of the time, SSO just means: You can use the same account in different applications.

\n\n

But some argue that a “real” SSO experience should mean: You log in to your Windows Desktop environment, and that’s it - each application should just use the existing Windows account.

\n\n

Problems

\n\n

With “Integrated Windows Auth,” this was quite easy, but with Entra ID, it seems really hard. Even Microsoft seems to struggle with this task, because even Microsoft Teams and Office need at least a hint like an email address to sign in the actual user.

\n\n

Solution?

\n\n

I _didn’t__ found a solution for this (complex) problem, but I found a few interesting tools/links that might help achieve it.

\n\n

Please let me know if you find a solution 😉

\n\n

“dsregcmd”

\n\n

There is a tool called dsregcmd, which stands for “Directory Service Registration” and shows how your device is connected to Azure AD.

\n\n
PS C:\\Users\\muehsig> dsregcmd /?\nDSREGCMD switches\n                        /? : Displays the help message for DSREGCMD\n                   /status : Displays the device join status\n               /status_old : Displays the device join status in old format\n                     /join : Schedules and monitors the Autojoin task to Hybrid Join the device\n                    /leave : Performs Hybrid Unjoin\n                    /debug : Displays debug messages\n               /refreshprt : Refreshes PRT in the CloudAP cache\n          /refreshp2pcerts : Refreshes P2P certificates\n          /cleanupaccounts : Deletes all WAM accounts\n             /listaccounts : Lists all WAM accounts\n             /UpdateDevice : Update device attributes to Azure AD\n
\n\n

In Windows 11 - as far as I know - a new command was implemented: /listaccounts

\n\n

dsregcmd /listaccounts

\n\n

This command lists all “WAM” accounts from my current profile:

\n\n

The ...xxxx... is used to hide information

\n\n
PS C:\\Users\\muehsig> dsregcmd /listaccounts\nCall ListAccounts to list WAM accounts from the current user profile.\nUser accounts:\nAccount: u:a17axxxx-xxxx-xxxx-xxxx-1caa2b93xxxx.85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx, user: xxxx.xxxx@xxxx.com, authority: https://login.microsoftonline.com/85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx.\nAccounts found: 1.\nApplication accounts:\nAccounts found: 0.\nDefault account: u:a17axxxx-xxxx-xxxx-xxxx-1caa2b93xxxx.85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx, user: xxxx.xxxx@xxxx.com.\n
\n\n

What is WAM?

\n\n

It’s not the cool x-mas band with the fancy song (that we all love!).

\n\n

WAM stands for Web Account Manager and it integrates with the Windows Email & accounts setting:

\n\n

\"x\"

\n\n

WAM can also be used to obtain a Token - which might be the right direction for my SSO question, but I couldn’t find the time to test this out.

\n\n

“Connected to Windows”

\n\n

This is now pure speculation, because I couldn’t find any information about it, but I think the “Connected to Windows” hint here:

\n\n

\"x\"

\n\n

… is based on the Email & accounts setting (= WAM), and with dsregcmd /listaccounts I can see diagnostic information about it.

\n\n

“Seamless single sign-on”

\n\n

I found this troubleshooting guide and it seems that there is a thing called “seamless single sign-on”, but I’m not 100% sure if this is more a “Development” topic or “IT-Pro” topic (or a mix of both).

\n\n

TIL

\n\n

I (and you!) have learned about a tool called dsregcmd.

\n\n

Try out the dsregcmd /status, it’s like ipconfig /all, but for information about AD connectivity.

\n\n

WAM plays an important part with the “Email & accounts” setting and maybe this is the right direction for the actual SSO topic.

\n\n

Open questions…

\n\n

Some open questions:

\n\n\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/08/06/dsregcmd-wam-and-connected-to-windows-accounts/","RawContent":null,"Thumbnail":null},{"Title":"SQL ConnectionString: Encrypt & Trust Server Certificate","PublishedOn":"2024-07-22T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

In our product, we store all data in an MS SQL database. One of our clients had issues with the SQL connection, and I want to share what I learned about SQL Encryption and how (some) properties of the Connection String affect the behavior.

\n\n

Basic SQL Connection String

\n\n

In general, we have a pretty easy setup:

\n\n

Our application reads a typical connection string that looks like this Data Source=your-sql-server.yourcorp.local;Initial Catalog=database_x;User ID=username;Password=password_here;MultipleActiveResultSets=True;Encrypt=False or (for Windows Authentication) Integrated Security=true instead of User ID=username;Password=password_here, and uses the (new) Microsoft.Data.SqlClient to connect to the database.

\n\n

Let’s look at all applied properties:

\n\n\n\n

Since Version 4.0 of the Microsoft.Data.SqlClient the Encrypt property defaults to true instead of false, and now we are entering the field of encryption…

\n\n

Encryption

\n\n

We usally use Encrypt=False, because in most cases, there is no proper certificate installed on the SQL Server - at least this is our experience with our clients. If a client has a proper setup, we recommend using it, of course, but most of the time there is none.

\n\n

With Encrypt=True, the data between the client and the server is TLS encrypted (and this is a good thing, and the breaking change therefore had a good intention).

\n\n

If you are interested how to set it up, this might be a good starting point for you: Configure SQL Server Database Engine for encrypting connections

\n\n

In some cases, your client might not be able to trust the server certificate (e.g. there is just a self-signed cert installed on the SQL server). Then you can disable the certification validation via TrustServerCertification, but this shouldn’t be used (at least in production) or handled with care. If the certificate doesn’t match the name of the Data Source, then you can use HostNameInCertificate.

\n\n

What have I learned?

\n\n

I already knew about Encrypt=True or Encrypt=False, but the behavior of TrustServerCertification (and when to use it) was new for me. This Stackoverflow-question helped me a lot to discover it.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/07/22/sql-connectionstring-encrypt-and-trustservercertificate/","RawContent":null,"Thumbnail":null},{"Title":"LLamaSharp: Run a ChatGPT like system on your hardware for dummies","PublishedOn":"2024-05-15T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

TL;DR summary: Check out the LLamaSharp Quick Start and you will find everything that you need to know

\n\n

ChatGPT (and all those Microsoft Copilots out there that were build on top of this) is currently the synonym for AI based chat systems. As a dev you can just use the Azure OpenAI Services and integrate this in your app - I blogged about this last year.

\n\n

The only “downside” is, that you rely on a cloud system, that costs money and you need to trust the overall system and as a tech nerd it is always “cool” to host stuff yourself.\nOf course, there are a lot of other good reasons why hosting such a system yourself is a good idea, but we just stick with “it is cool” for this blogpost. (There are tons of reasons why this is a stupid idea as well, but we might do it anyway just for fun.)

\n\n

Is there something for .NET devs?

\n\n

My AI knowledge is still quite low and I’m more a “.NET backend developer”, so I was looking for an easy solution for my problem and found “LLamaSharp”.

\n\n

This blogpost and my experiment was inspired by Maarten Balliauws blog post “Running Large Language Models locally – Your own ChatGPT-like AI in C#”, which is already a year old, but still a good intro in this topic.

\n\n

LLamaSharp

\n\n

From their GitHub Repo:

\n\n
\n

LLamaSharp is a cross-platform library to run 🦙LLaMA/LLaVA model (and others) on your local device. Based on llama.cpp, inference with LLamaSharp is efficient on both CPU and GPU. With the higher-level APIs and RAG support, it’s convenient to deploy LLM (Large Language Model) in your application with LLamaSharp.

\n
\n\n

Be aware: This blogpost is written with LLamaSharp version 0.12.0 - Maartens blogpost is based on version 0.3.0 and the model he was using is not working anymore.

\n\n

This sounds really good - let’s checkout the quick start

\n\n

The basic steps are easy: Just add the LLamaSharp and LLamaSharp.Backend.Cpu NuGet package to your project and then search for a model… but where?

\n\n

The model

\n\n

From the quick start:

\n\n
\n

There are two popular format of model file of LLM now, which are PyTorch format (.pth) and Huggingface format (.bin). LLamaSharp uses GGUF format file, which could be converted from these two formats. To get GGUF file, there are two options:

\n\n

Search model name + ‘gguf’ in Huggingface, you will find lots of model files that have already been converted to GGUF format. Please take care of the publishing time of them because some old ones could only work with old version of LLamaSharp.

\n\n

Convert PyTorch or Huggingface format to GGUF format yourself. Please follow the instructions of this part of llama.cpp readme to convert them with the python scripts.

\n\n

Generally, we recommend downloading models with quantization rather than fp16, because it significantly reduce the required memory size while only slightly impact on its generation quality.

\n
\n\n

Okay… I ended up using the huggingface-search-approach and picked the Phi-3-mini-4k-instruct-gguf, because I heard about it somewhere.

\n\n

Code

\n\n

After the initial search and download I could just copy/paste the quick start code in my project and hit run:

\n\n
using LLama.Common;\nusing LLama;\n\nstring modelPath = @\"C:\\temp\\Phi-3-mini-4k-instruct-q4.gguf\"; // change it to your own model path.\n\nvar parameters = new ModelParams(modelPath)\n{\n    ContextSize = 1024, // The longest length of chat as memory.\n    GpuLayerCount = 2 // How many layers to offload to GPU. Please adjust it according to your GPU memory.\n};\nusing var model = LLamaWeights.LoadFromFile(parameters);\nusing var context = model.CreateContext(parameters);\nvar executor = new InteractiveExecutor(context);\n\n// Add chat histories as prompt to tell AI how to act.\nvar chatHistory = new ChatHistory();\nchatHistory.AddMessage(AuthorRole.System, \"Transcript of a dialog, where the User interacts with an Assistant named Bob. Bob is helpful, kind, honest, good at writing, and never fails to answer the User's requests immediately and with precision.\");\nchatHistory.AddMessage(AuthorRole.User, \"Hello, Bob.\");\nchatHistory.AddMessage(AuthorRole.Assistant, \"Hello. How may I help you today?\");\n\nChatSession session = new(executor, chatHistory);\n\nInferenceParams inferenceParams = new InferenceParams()\n{\n    MaxTokens = 256, // No more than 256 tokens should appear in answer. Remove it if antiprompt is enough for control.\n    AntiPrompts = new List<string> { \"User:\" } // Stop generation once antiprompts appear.\n};\n\nConsole.ForegroundColor = ConsoleColor.Yellow;\nConsole.Write(\"The chat session has started.\\nUser: \");\nConsole.ForegroundColor = ConsoleColor.Green;\nstring userInput = Console.ReadLine() ?? \"\";\n\nwhile (userInput != \"exit\")\n{\n    await foreach ( // Generate the response streamingly.\n        var text\n        in session.ChatAsync(\n            new ChatHistory.Message(AuthorRole.User, userInput),\n            inferenceParams))\n    {\n        Console.ForegroundColor = ConsoleColor.White;\n        Console.Write(text);\n    }\n    Console.ForegroundColor = ConsoleColor.Green;\n    userInput = Console.ReadLine() ?? \"\";\n}\n
\n\n

The result is a “ChatGPT-like” chat bot (maybe not so smart, but it runs quick ok-ish on my Dell notebook:

\n\n

\"x\"

\n\n

Summary

\n\n

After some research which model can be used with LLamaSharp it went really smoothly (even for a .NET dummy like me).

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/05/15/llamasharp-run-a-chatgpt-like-system-on-your-hardware-for-dummies/","RawContent":null,"Thumbnail":null},{"Title":"dotnet dev-certs https - How .NET Issues Your Local Dev HTTPS Certificate","PublishedOn":"2024-03-15T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If you start developing a ASP.NET Core application you will notice that your site is running under “http s ://localhost:1234” and that your browser is happy to accept it - so there are some questions to be asked.

\n\n

Why HTTPS on your local dev box?

\n\n

The first question might be: Why is HTTPS on your local dev box even needed?

\n\n

At least two reasons for this (from my perspective):

\n\n\n

I wouldn’t count “security” as an issue here, because you are developing on your own system. If there is something on your machine HTTPS won’t help you at that point.

\n\n

How does ASP.NET Core issues a valid & trusted cert?

\n\n

I’m not exactly sure when this happens, as it was already installed on my development machine.

\n\n

Either when you install the Visual Studio workload for ASP.NET Core or if you create your very first ASP.NET Core application the dev cert for localhost will be issued.

\n\n

But how?

\n\n

The .NET SDK ships with a CLI tool called dotnet dev-certs https and this tool issues the certificate.\nThe output of this command will look like this if a valid and trusted certificate is found::

\n\n
PS C:\\Users\\muehsig> dotnet dev-certs https\nA valid HTTPS certificate is already present.\n
\n\n

dev-certs https

\n\n

There are other options available:

\n\n
PS C:\\Users\\muehsig> dotnet dev-certs https --help\n\n\nUsage: dotnet dev-certs https [options]\n\nOptions:\n  -ep|--export-path  Full path to the exported certificate\n  -p|--password      Password to use when exporting the certificate with the private key into a pfx file or to encrypt the Pem exported key\n  -np|--no-password  Explicitly request that you don't use a password for the key when exporting a certificate to a PEM format\n  -c|--check         Check for the existence of the certificate but do not perform any action\n  --clean            Cleans all HTTPS development certificates from the machine.\n  -i|--import        Imports the provided HTTPS development certificate into the machine. All other HTTPS developer certificates will be cleared out\n  --format           Export the certificate in the given format. Valid values are Pfx and Pem. Pfx is the default.\n  -t|--trust         Trust the certificate on the current platform. When combined with the --check option, validates that the certificate is trusted.\n  -v|--verbose       Display more debug information.\n  -q|--quiet         Display warnings and errors only.\n  -h|--help          Show help information\n
\n\n

What happens when the cert is no longer valid?

\n\n

This is an interesting one, because I had this experience just this week (and that’s the reason for this blogpost).

\n\n

A certificate needs to be in the certification store to be considered trusted. That means your “localhost”-dev cert will be stored in your personal certification store (at least on Windows):

\n\n

\"x\"

\n\n

As you can see, the command dotnet dev-certs https --check --trust will return something like this:

\n\n
A trusted certificate was found: E7A2FB302F26BCFFB7C21801C09081CF2FAAAD2C - CN=localhost - Valid from 2024-03-13 11:12:10Z to 2025-03-13 11:12:10Z - IsHttpsDevelopmentCertificate: true - IsExportable: true\n
\n\n

If the certificate is stale, then your browser won’t accept it anymore and your web application will start, but can’t be viewed because your browser will refuse it.

\n\n

How to repair invalid certificates?

\n\n

Use the two commands and it should work again:

\n\n
dotnet dev-certs https --clean\n
\n\n

…which will remove the old certification and…

\n\n
dotnet dev-certs https --trust\n
\n\n

… to issue a new cert and invoke the trust dialog from Windows.

\n\n

If it works…

\n\n

There are some more options, e.g. to export the certificate, which can be useful in certain scenarios, but if you can use HTTPS on your local development machine and everything works you shouldn’t have to bother.\nIf you want to learn more, checkout the dotnet dev-certs documentation.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/03/15/dotnet-dev-certs-https/","RawContent":null,"Thumbnail":null},{"Title":".NET Upgrade Assistant","PublishedOn":"2024-03-07T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

For those facing the challenge of migrating their .NET Framework-based application to the modern .NET stack, Microsoft’s “Upgrade Assistant” is highly recommended:

\n\n\n\n

What is the “Upgrade Assistant”?

\n\n

The “Upgrade Assistant” is a tool that can integrate into Visual Studio or be accessed via CLI.\nIf you install the extension for Visual Studio you will have a new option “Upgrade project” available in your Solution Explorer.

\n\n

.NET Framework to “new” and more…

\n\n

Its main use case is upgrading .NET Framework-based WPF, WinForms, class libraries, or web applications to the newest .NET version. Besides this, the tool offers some other migration paths as well, e.g. from UWP to WinUI 3.

\n\n

You even can use the tool to migrate from an older .NET Core version to a newer version (but - to be honest: those upgrades are quite easy in contrast to the .NET Framework to .NET Core migration).

\n\n

Depending on the project type, the assistant allows for an “In-Place Upgrade,” “Side-by-Side,” or “Side-by-Side Incremental” upgrade.

\n\n\n\n

You can see those upgrade methods in the video above.

\n\n

Is it good?

\n\n

We have used (or at least tested) the Assistant for upgrading WPF and class libraries to .NET Core and it helps to identify problems (e.g. if a NuGet package or any “old” framework code is not compatible).\nMy verdict: If you need to upgrade your code, you should give it a try.\nIn a more complex code base, it will sometimes mess with the code, but it still helps to give directions.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/03/07/upgrade-assistant/","RawContent":null,"Thumbnail":null},{"Title":"WinUI 3 Community Toolkit and the Template Studio","PublishedOn":"2024-02-24T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In my last post “First steps with WinUI 3” I already mentioned the “WinUI 3 Gallery”-App, but I missed mentioning two great resources.

\n\n

If you take a deeper look at the “Home” page, you will spot the Community Toolkit Gallery (another app) and the “Template Studio for WinUI”.

\n\n

\"x\"

\n\n

What is the Community Toolkit?

\n\n

The Community Toolkit is a community-driven collection of components and other helpers.

\n\n

\"x\"

\n\n

The “home” of the Community Toolkit can be found on GitHub

\n\n

As of today, the Community Toolkit seems “alive” with recent commits in February 2024.

\n\n

Interesting fact: The controls from the toolkit seems to work with the Uno Platform as well.

\n\n

What is the Template Studio?

\n\n

Template Studio is an addin for Visual Studio and can be installed from the Marketplace.

\n\n

This adds the ‘Template Studio for WinUI’ template to Visual Studio:

\n\n

\"x\"

\n\n

After the usual “pick a name and location” you will be greeted with this Wizard:

\n\n

The first step is to select a “Project type”:

\n\n

\"x\"

\n\n

In the next step you choose a “Design pattern” - which has only one item… well.

\n\n

\"x\"

\n\n

In “Pages” you can create your “views/pages” based on a given layout:

\n\n

Some pages can only be added once (e.g. the “Settings”), but most pages can be added multiple times.

\n\n

\"x\"

\n\n

In “Features” you can add some WinUI 3 related features:

\n\n

\"x\"

\n\n

In the last setting you can decide if you want to add an MSTest project as well:

\n\n

\"x\"

\n\n

The result is the following Visual Studio solution, which includes two projects and a number of TODO items:

\n\n

\"x\"

\n\n

If you run the code a pretty simple app with your configured pages will be found:

\n\n

\"x\"

\n\n

Warning: Such code generators might be a good starting point, but (as always with such generators) the code might be “too stupid” or “too complicated” - depending on your needs.

\n\n

Any other useful resource?

\n\n

I’m a newbie with WinUI 3. The Community Toolkit looks promising and even the Template Studio looks good - at least from a few minutes playtime. If anyone has other useful resource: Please let me know (e.g. in the comments or via email).

\n\n

Hope this helps!

\n\n","Href":"https://blog.codeinside.eu/2024/02/24/winui3-with-community-toolkit-and-template-studio/","RawContent":null,"Thumbnail":null},{"Title":"First steps with WinUI 3","PublishedOn":"2024-02-12T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Developing desktop apps for Windows is quite complex in 2024. There are some “old school” frameworks like WPF or WinForms (or even older stuff) and there is this confusing UWP (but I think it’s dead). \nThe “modern stack” seems to be WinUI - so let’s take a look.

\n\n

\"x\"

\n\n

See here

\n\n

What is WinUI?

\n\n

WinUI is the “modern” version of WPF without the (dumb?) constraints from UWP. You can of course use your typical “Windows” programming languages (like C# or C++).

\n\n

If you heard of UWP. The “Universal Windows Platform” was a good idea but failed, because - at least from my limited testing - the platform was very strict and you couldn’t do the same stuff that you can do with WPF/WinForms.

\n\n

WinUI 1 and 2 were targeted at UWP (if I remember correctly) and with WinUI 3 Microsoft decided to lift those UWP constraints and with it we get a modern desktop stack based on the “known” XAML.

\n\n

In summary:

\n\n

WinUI 3 apps can be used for apps that run on Windows 11 and Windows 10 and can be distributed via the Microsoft Store and you can do the same crazy stuff that you love about WPF/WinForms.

\n\n

Does anybody outside of Microsoft use WinUI?

\n\n

WinUI is used in Windows 11, e.g. the settings or the new explorer - which is nice, but it would be good, if we found a non-Microsoft app that uses this tech, right?

\n\n

Thankfully last week Apple decided to release Apple Music (and other apps) as a native Windows app and it seems (confirmed) like it was written with WinUI:

\n\n

\"x\"

\n\n

If Apple uses this tech, it seems “safe enough” for some exploration.

\n\n

How to get started?

\n\n

You will need Visual Studio 2022. Be aware, that even if you check all those desktop related workloads in the installer the WinUI 3 templates are still missing.

\n\n

\"x\"

\n\n

For the WinUI 3 templates you will need to install the Windows App SDK.

\n\n

Visual Studio Templates

\n\n

After the Windows App SDK is installed we finally have the templates in Visual Studio:

\n\n

\"x\"

\n\n

The default Blank App, Packaged (WinUI 3 in Desktop) is… well… quite blank:

\n\n

\"x\"

\n\n

If you start the application, you will see this:

\n\n

\"x\"

\n\n

Packaged vs. Unpacked

\n\n

If you check the toolbar, you will notice the App 6 (Package) debug button. Packaged Apps can access some Windows APIs (e.g. custom context menu extensions) that Unpackaged Apps can’t. Unpackaged Apps on the other hand act like WPF apps - e.g. they have a “normal” .exe and can be distributed like any .exe-file.

\n\n

This documentation page should cover this topic.

\n\n

Let’s say we want to have a “proper” myApp.exe app, then the Unpackaged App is the way to go. If you choose the App 6 (Unpackaged) debug option you might see this weird error:

\n\n
XamlCheckProcessRequirements();\n\nException Unhandled:\nSystem.DllNotFoundException: 'Unable to load DLL 'Microsoft.ui.xaml.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)'\n
\n\n

To fix this, you will need to add this to the .csproj:

\n\n
\t<PropertyGroup>\n\t\t...\n\t\t<WindowsPackageType>None</WindowsPackageType>\n        ...\n\t</PropertyGroup>\n
\n\n

After that the debug button should start the application and you should be able to start the .exe.

\n\n

Samples

\n\n

Ok, the most basic steps are done - now what?

\n\n

To get a feeling about what is possible and what not, you should install the WinUI 3 Gallery app.

\n\n

\"x\"

\n\n

This application should give a some guidiance.

\n\n

Hope this helps!

\n\n

Note: I’m a beginner with WinUI 3 and just want to show other people the first few steps - if I miss something, just write me a comment! Thanks <3

\n\n","Href":"https://blog.codeinside.eu/2024/02/12/first-steps-with-winui3/","RawContent":null,"Thumbnail":null},{"Title":"How Windows locates an executable via PATH or App Paths","PublishedOn":"2024-01-17T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If you’ve ever worked with the Windows operating system, especially in a programming context, you might have used the Process.Start(yourapp) (e.g. Process.Start(Outlook)) method in languages like C#.\nThis method is used to start a process - essentially to run an executable file. But have you ever stopped to think about how Windows knows where to find the executables you’re trying to run? Let’s dive into the inner workings of Windows and uncover this mystery.

\n\n

Understanding the PATH Environment Variable

\n\n

One of the first things that come into play is the PATH environment variable. This variable is crucial for the operating system to locate the executables.

\n\n

What is the PATH Variable?

\n\n

The PATH environment variable is a system-wide or user-specific setting that lists directories where executable files are stored. When you run a command in the command prompt or use Process.Start(...), Windows looks through these directories to find the executable file.

\n\n

The PATH environment variable can be viewed via the system settings:

\n\n

\"x\"

\n\n

… there is also a nice editor now build into Windows for the PATH environment variable:

\n\n

\"x\"

\n\n

How Does PATH Work?

\n\n

If the executable is not in the current directory, Windows searches through each directory specified in the PATH variable. The order of directories in PATH is important - Windows searches them in the order they are listed. If it finds the executable in one of these directories, it runs it.

\n\n

However, the PATH variable isn’t the only mechanism at play here.

\n\n

The Role of App Paths in the Windows Registry

\n\n

Another less-known but equally important component is the “App Paths” registry key. This key is located in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths.

\n\n

Understanding App Paths

\n\n

The App Paths key is used to specify paths to specific applications. Each application can have its entry under the App Paths key, which means that Windows can find and run these applications even if their directories are not listed in the PATH variable.

\n\n

\"x\"

\n\n

How Do App Paths Work?

\n\n

When you use Process.Start(...) and specify an application name like “OUTLOOK”, Windows first checks the App Paths registry key before it checks the PATH variable. If it finds an entry for the application here, it uses this path to start the application. This is particularly useful for applications that are not in common directories or have multiple executables in different locations.

\n\n

Conclusion

\n\n

Both PATH and App Paths play significant roles. While PATH is great for general-purpose directory searching (especially for system utilities and command-line tools), App Paths is more specific and tailored for individual applications.

\n\n

There are probably even more options out there besides PATH and App Paths - Windows is full of hidden gems like this 😉.

\n\n

Fun fact: I only discovered App Paths while debugging a problem. We use Process.Start(OUTLOOK) to start Microsofts Outlook Client and I was wondering why this even works.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/01/17/windows-path-and-app-paths/","RawContent":null,"Thumbnail":null},{"Title":".NET ('.NET Core') and Proxy Settings","PublishedOn":"2024-01-12T22:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If your .NET (“.NET Core”) program is running on a system that specifies strict proxy settings, you must either handle these settings in your application itself or use these environment variables.

\n\n

Since I had this problem from time to time and the procedure was not 100% clear to me, I am now recording it here on the blog.

\n\n

“DefaultProxy”

\n\n

If you don’t specify any proxy, then the DefaultProxy is used and depending on your operation system the following will be used:

\n\n

(Copied from here)

\n\n
\n

For Windows: Reads proxy configuration from environment variables or, if those are not defined, from the user’s proxy settings.

\n\n

For macOS: Reads proxy configuration from environment variables or, if those are not defined, from the system’s proxy settings.

\n\n

For Linux: Reads proxy configuration from environment variables or, in case those are not defined, this property initializes a non-configured instance that bypasses all addresses.\nThe environment variables used for DefaultProxy initialization on Windows and Unix-based platforms are:

\n\n

HTTP_PROXY: the proxy server used on HTTP requests.\nHTTPS_PROXY: the proxy server used on HTTPS requests.\nALL_PROXY: the proxy server used on HTTP and/or HTTPS requests in case HTTP_PROXY and/or HTTPS_PROXY are not defined.\nNO_PROXY: a comma-separated list of hostnames that should be excluded from proxying. Asterisks are not supported for wildcards; use a leading dot in case you want to match a subdomain. Examples: > NO_PROXY=.example.com (with leading dot) will match www.example.com, but will not match example.com. NO_PROXY=example.com (without leading dot) will not match www.example.com. This behavior might be > revisited in the future to match other ecosystems better.

\n
\n\n

Scenario: Web-App that needs external & “internal” Web-APIs

\n\n

We often had the following problem: \nOur web application needs to contact external services. This means, that we must use the proxy.\nAt the same time, our web application also wants to communicate with other web APIs on the same machine, but the proxy does not allow this (the proxy can’t return the request to the same machine - not sure why).

\n\n

It should be noted that the “IIS account” or “Network Service” did NOT have a proxy setting itself, i.e. the “User Proxy Settings” were always empty.

\n\n

Solution:

\n\n

We used the following proxy settings and it worked:

\n\n
ALL_PROXY = proxyserver.corp.acme.com\nNO_Proxy = internalserver.corp.acme.com\n
\n\n

Our web application and our internal web api were running on “internalserver.corp.acme.com”. Each request to external services were routed through the proxy and each “internal” request didn’t touch the proxy.

\n\n

IE-Proxy Settings:

\n\n

This solution should work fine on “Server-Environments”. If you have a desktop application, then the “Default Proxy” handling should do the trick. In some special cases the “IE proxy setting” handling might be needed. If you want to learn more about this, read this blogpost: How to use IE proxy settings with HttpClient.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/01/12/dotnetcore-and-proxy-settings/","RawContent":null,"Thumbnail":null},{"Title":"Limit Active Directory property access","PublishedOn":"2023-09-20T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Be aware: I’m not a full time administrator and this post might sound stupid to you.

\n\n

The Problem

\n\n

We access certain Active Directory properties with our application, and on one customer domain, we couldn’t retrieve any data via our Active Directory component.

\n\n

Solution

\n\n

After some debugging and doubts about our functionality, the customer admin and I found the reason:\nOur code was running under a Windows account that was very limited and couldn’t read those properties.

\n\n

If you have similar problems, you might want to look into the AD User & Group management.

\n\n

First step: You need to active the advanced features:

\n\n

\"x\"

\n\n

Now navigate to your “user OU” or the target users and check the security tab. The goal is to grant your service account the permission to read the needed property. To do that, go to the advanced view, and add a new permission or change an existing one:

\n\n

\"x\"

\n\n

Here you should be able to see a huge dialog with all available properties and grant the read permission for the target property for your service account.

\n\n

\"x\"

\n\n

Solution via CMD

\n\n

The UI is indeed quite painful to use. If you know what you are doing you can use dsacls.exe.

\n\n

To grant the read permission for tokenGroups for a certain service account you can use the tool like this:

\n\n
dsacls \"OU=Users,DC=company,DC=local\" /I:S /G \"service_account\":rp;tokenGroups;user\n
\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/09/20/limit-active-directory-property-access/","RawContent":null,"Thumbnail":null},{"Title":"Zip deployment failed on Azure","PublishedOn":"2023-09-05T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The Problem

\n\n

We are using Azure App Service for our application (which runs great BTW) and deploy it automatically via ZipDeploy. \nThis basic setup was running smoth, but we noticed that at some point the deployment failed with these error messages:

\n\n
2023-08-24T20:48:56.1057054Z Deployment endpoint responded with status code 202\n2023-08-24T20:49:15.6984407Z Configuring default logging for the app, if not already enabled\n2023-08-24T20:49:18.8106651Z Zip deployment failed. {'id': 'temp-b574d768', 'status': 3, 'status_text': '', 'author_email': 'N/A', 'author': 'N/A', 'deployer': 'ZipDeploy', 'message': 'Deploying from pushed zip file', 'progress': '', 'received_time': '2023-08-24T20:48:55.8916655Z', 'start_time': '2023-08-24T20:48:55.8916655Z', 'end_time': '2023-08-24T20:49:15.3291017Z', 'last_success_end_time': None, 'complete': True, 'active': False, 'is_temp': True, 'is_readonly': False, 'url': 'https://[...].scm.azurewebsites.net/api/deployments/latest', 'log_url': 'https://[...].scm.azurewebsites.net/api/deployments/latest/log', 'site_name': '[...]', 'provisioningState': 'Failed'}. Please run the command az webapp log deployment show\n2023-08-24T20:49:18.8114319Z                            -n [...] -g production\n
\n\n

or this one (depending on how we invoked the deployment script):

\n\n
Getting scm site credentials for zip deployment\nStarting zip deployment. This operation can take a while to complete ...\nDeployment endpoint responded with status code 500\nAn error occured during deployment. Status Code: 500, Details: {\"Message\":\"An error has occurred.\",\"ExceptionMessage\":\"There is not enough space on the disk.\\r\\n\",\"ExceptionType\":\"System.IO.IOException\",\"StackTrace\":\" \n
\n\n

“There is not enough space on the disk”?

\n\n

The message There is not enough space on the disk was a good hint, but according to the File system storage everything should be fine with only 8% used.

\n\n

Be aware - this is important: We have multiple apps on the same App Service plan!

\n\n

\"x\"

\n\n

Kudu to the rescure

\n\n

Next step was to check the behind the scene environment via the “Advanced Tools” Kudu and there it is:

\n\n

\"x\"

\n\n

There are two different storages attached to the app service:

\n\n\n\n

Who is using this space?

\n\n

c:\\local stores “mostly” temporarily items, e.g.:

\n\n
Directory of C:\\local\n\n08/31/2023  06:40 AM    <DIR>          .\n08/31/2023  06:40 AM    <DIR>          ..\n07/13/2023  04:29 PM    <DIR>          AppData\n07/13/2023  04:29 PM    <DIR>          ASP Compiled Templates\n08/31/2023  06:40 AM    <DIR>          Config\n07/13/2023  04:29 PM    <DIR>          DomainValidationTokens\n07/13/2023  04:29 PM    <DIR>          DynamicCache\n07/13/2023  04:29 PM    <DIR>          FrameworkJit\n07/13/2023  04:29 PM    <DIR>          IIS Temporary Compressed Files\n07/13/2023  04:29 PM    <DIR>          LocalAppData\n07/13/2023  04:29 PM    <DIR>          ProgramData\n09/05/2023  08:36 PM    <DIR>          Temp\n08/31/2023  06:40 AM    <DIR>          Temporary ASP.NET Files\n07/18/2023  04:06 AM    <DIR>          UserProfile\n08/19/2023  06:34 AM    <SYMLINKD>     VirtualDirectory0 [\\\\...\\]\n               0 File(s)              0 bytes\n              15 Dir(s)  13,334,384,640 bytes free\n
\n\n

The “biggest” item here was in our case under c:\\local\\Temp\\zipdeploy:

\n\n
 Directory of C:\\local\\Temp\\zipdeploy\n\n08/29/2023  04:52 AM    <DIR>          .\n08/29/2023  04:52 AM    <DIR>          ..\n08/29/2023  04:52 AM    <DIR>          extracted\n08/29/2023  04:52 AM       774,591,927 jiire5i5.zip\n
\n\n

This folder stores our ZipDeploy package, which is quite large with ~800MB. The folder also contains the extracted files - remember: We only have 21GB on this storage, but even if this zip file and the extracted files are ~3GB, there is still plenty of room, right?

\n\n

Shared resources

\n\n

Well… it turns out, that each App Service on a App Service plan is using this storage and if you have multiple App Services on the same plan, than those 21GB might melt away.

\n\n

The “bad” part is, that the space is shared, but each App Services has it’s own c:\\local folder (which makes sense). To free up memory we had to clean up this folder on each App Service like that:

\n\n
rmdir c:\\local\\Temp\\zipdeploy /s /q\n
\n\n

TL;DR

\n\n

If you have problems with ZipDeploy and the error message tells you, that there is not enough space, check out the c:\\local space (and of course c:\\home as well) and delete unused files. Sometimes a reboot might help as well (to clean up temp-files), but AFAIK those ZipDeploy files will survive that.

\n\n","Href":"https://blog.codeinside.eu/2023/09/05/zip-deployment-failed-on-azure-and-how-to-fix-it/","RawContent":null,"Thumbnail":null},{"Title":"First steps with Azure OpenAI and .NET","PublishedOn":"2023-03-23T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The AI world is rising very fast these days: ChatGPT is such an awesome (and scary good?) service and Microsoft joined the ship with some partner announcements and investments. The result is of these actions is, that OpenAI is now a “first class citizen” on Azure.

\n\n

So - for the average Microsoft/.NET developer this opens up a wonderful toolbox and the first steps are really easy.

\n\n

Be aware: You need to “apply” to access the OpenAI service, but it took less then 24 hours for us to gain access to the service. I guess this is just a temporary thing.

\n\n

Disclaimer: I’m not an AI/ML engineer and I only have a very “glimpse” knowledge about the technology behind GPT3, ChatGPT and ML in general. If in doubt, I always ask my buddy Oliver Guhr, because he is much smarter in this stuff. Follow him on Twitter!

\n\n

1. Step: Go to Azure OpenAI Service

\n\n

Search for “OpenAI” and you will see the “Azure OpenAI Service” entry:

\n\n

\"x\"

\n\n

2. Step: Create a Azure OpenAI Service instance

\n\n

Create a new Azure OpenAI Service instance:

\n\n

\"x\"

\n\n

On the next page you will need to enter the subscription, resource group, region and a name (typical Azure stuff):

\n\n

\"x\"

\n\n

Be aware: If your subscription is not enabled for OpenAI, you need to apply here first.

\n\n

3. Step: Overview and create a model

\n\n

After the service is created you should see something like this:

\n\n

\"x\"

\n\n

Now go to “Model deployments” and create a model - I choosed “text-davinci-003”, because I think this is GPT3.5 (which was the initial ChatGPT release, GPT4 is currently in preview for Azure and you need to apply again.

\n\n

\"x\"

\n\n

My guess is, that you could train/deploy other, specialized models here, because this model is quite complex and you might want to tailor the model for your scenario to get faster/cheaper results… but I honestly don’t know how to do it (currently), so we just leave the default.

\n\n

4. Step: Get the endpoint and the key

\n\n

In this step we just need to copy the key and the endpoint, which can be found under “Keys and Endpoint”, simple - right?

\n\n

\"x\"

\n\n

5. Step: Hello World to our Azure OpenAI instance

\n\n

Create a .NET application and add the Azure.AI.OpenAI NuGet package (currently in preview!).

\n\n
dotnet add package Azure.AI.OpenAI --version 1.0.0-beta.5\n
\n\n

Use this code:

\n\n
using Azure.AI.OpenAI;\nusing Azure;\n\nConsole.WriteLine(\"Hello, World!\");\n\nOpenAIClient client = new OpenAIClient(\n        new Uri(\"YOUR-ENDPOINT\"),\n        new AzureKeyCredential(\"YOUR-KEY\"));\n\nstring deploymentName = \"text-davinci-003\";\nstring prompt = \"Tell us something about .NET development.\";\nConsole.Write($\"Input: {prompt}\");\n\nResponse<Completions> completionsResponse = client.GetCompletions(deploymentName, prompt);\nstring completion = completionsResponse.Value.Choices[0].Text;\n\nConsole.WriteLine(completion);\n\nConsole.ReadLine();\n\n
\n\n

Result:

\n\n
Hello, World!\nInput: Tell us something about .NET development.\n\n.NET development is a mature, feature-rich platform that enables developers to create sophisticated web applications, services, and applications for desktop, mobile, and embedded systems. Its features include full-stack programming, object-oriented data structures, security, scalability, speed, and an open source framework for distributed applications. A great advantage of .NET development is its capability to develop applications for both Windows and Linux (using .NET Core). .NET development is also compatible with other languages such as\n
\n\n

As you can see… the result is cut off, not sure why, but this is just a simple demonstration.

\n\n

Summary

\n\n

With these basic steps you can access the OpenAI development world. Azure makes it easy to integrate in your existing Azure/Microsoft “stack”. Be aware, that you could also use the same SDK and use the endpoint from OpenAI. Because of billing reasons it is easier for us to use the Azure hosted instances.

\n\n

Hope this helps!

\n\n

Video on my YouTube Channel

\n\n

If you understand German and want to see it in action, check out my video on my Channel:

\n\n\n\n","Href":"https://blog.codeinside.eu/2023/03/23/first-steps-with-azure-openai-and-dotnet/","RawContent":null,"Thumbnail":null},{"Title":"How to fix: 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine","PublishedOn":"2023-03-18T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In our product we can interact with different datasource and one of these datasources was a Microsoft Access DB connected via OLEDB. This is really, really old, but still works, but on one customer machine we had this issue:

\n\n
'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine\n
\n\n

Solution

\n\n

If you face this issue, you need to install the provider from here.

\n\n

Be aware: If you have a different error, you might need to install the newer provider - this is labled as “2010 Redistributable”, but still works with all those fancy Office 365 apps out there.

\n\n

Important: You need to install the provider in the correct bit version, e.g. if you run under x64, install the x64.msi.

\n\n

The solution comes from this Stackoverflow question.

\n\n

Helper

\n\n

The best tip from Stackoverflow was these powershell commands to check, if the provider is there or not:

\n\n
(New-Object system.data.oledb.oledbenumerator).GetElements() | select SOURCES_NAME, SOURCES_DESCRIPTION \n\nGet-OdbcDriver | select Name,Platform\n
\n\n

This will return something like this:

\n\n
PS C:\\Users\\muehsig> (New-Object system.data.oledb.oledbenumerator).GetElements() | select SOURCES_NAME, SOURCES_DESCRIPTION\n\nSOURCES_NAME               SOURCES_DESCRIPTION\n------------               -------------------\nSQLOLEDB                   Microsoft OLE DB Provider for SQL Server\nMSDataShape                MSDataShape\nMicrosoft.ACE.OLEDB.12.0   Microsoft Office 12.0 Access Database Engine OLE DB Provider\nMicrosoft.ACE.OLEDB.16.0   Microsoft Office 16.0 Access Database Engine OLE DB Provider\nADsDSOObject               OLE DB Provider for Microsoft Directory Services\nWindows Search Data Source Microsoft OLE DB Provider for Search\nMSDASQL                    Microsoft OLE DB Provider for ODBC Drivers\nMSDASQL Enumerator         Microsoft OLE DB Enumerator for ODBC Drivers\nSQLOLEDB Enumerator        Microsoft OLE DB Enumerator for SQL Server\nMSDAOSP                    Microsoft OLE DB Simple Provider\n\n\nPS C:\\Users\\muehsig> Get-OdbcDriver | select Name,Platform\n\nName                                                   Platform\n----                                                   --------\nDriver da Microsoft para arquivos texto (*.txt; *.csv) 32-bit\nDriver do Microsoft Access (*.mdb)                     32-bit\nDriver do Microsoft dBase (*.dbf)                      32-bit\nDriver do Microsoft Excel(*.xls)                       32-bit\nDriver do Microsoft Paradox (*.db )                    32-bit\nMicrosoft Access Driver (*.mdb)                        32-bit\nMicrosoft Access-Treiber (*.mdb)                       32-bit\nMicrosoft dBase Driver (*.dbf)                         32-bit\nMicrosoft dBase-Treiber (*.dbf)                        32-bit\nMicrosoft Excel Driver (*.xls)                         32-bit\nMicrosoft Excel-Treiber (*.xls)                        32-bit\nMicrosoft ODBC for Oracle                              32-bit\nMicrosoft Paradox Driver (*.db )                       32-bit\nMicrosoft Paradox-Treiber (*.db )                      32-bit\nMicrosoft Text Driver (*.txt; *.csv)                   32-bit\nMicrosoft Text-Treiber (*.txt; *.csv)                  32-bit\nSQL Server                                             32-bit\nODBC Driver 17 for SQL Server                          32-bit\nSQL Server                                             64-bit\nODBC Driver 17 for SQL Server                          64-bit\nMicrosoft Access Driver (*.mdb, *.accdb)               64-bit\nMicrosoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb) 64-bit\nMicrosoft Access Text Driver (*.txt, *.csv)            64-bit\n
\n\n

Hope this helps! (And I hope you don’t need to deal with these ancient technologies for too long 😅)

\n","Href":"https://blog.codeinside.eu/2023/03/18/microsoft-ace-oledb-12-0-provider-is-not-registered/","RawContent":null,"Thumbnail":null},{"Title":"Resource type is not supported in this subscription","PublishedOn":"2023-03-11T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

I was playing around with some Visual Studio Tooling and noticed this error during the creation of a “Azure Container Apps”-app:

\n\n

Resource type is not supported in this subscription

\n\n

\"x\"

\n\n

Solution

\n\n

The solution is quite strange at first, but in the super configurable world of Azure it makes sense: You need to activate the Resource provider for this feature on your subscription. For Azure Container Apps you need the Microsoft.ContainerRegistry-resource provider registered:

\n\n

\"x\"

\n\n

It seems, that you can create such resources via the Portal, but if you go via the API (which Visual Studio seems to do) the provider needs to be registered at first.

\n\n

Some resource providers are “enabled by default”, other providers needs to be turned on manually. Check out this list for a list of all resource providers and the related Azure service.

\n\n

Be careful: I guess you should only enable the resource providers that you really need, otherwise your attack surface will get larger.

\n\n

To be honest: This was completly new for me - I do Azure since ages and never had to deal with resource providers. Always learning ;)

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/03/11/resource-type-is-not-supported-in-this-subscription/","RawContent":null,"Thumbnail":null},{"Title":"Azure DevOps Server 2022 Update","PublishedOn":"2023-02-15T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Azure DevOps Server 2022 - OnPrem?

\n\n

Yes I know - you can get everything from the cloud nowadays, but we are still using our OnPrem hardware and were running the “old” Azure DevOps Server 2020. \nThe _Azure DevOps Server 2022 was released last december, so an update was due.

\n\n

Requirements

\n\n

If you are running am Azure DevOps Server 2020 the requirements for the new 2022 release are “more or less” the same except the following important parts:

\n\n\n\n

Make sure you have a backup

\n\n

The last requirement was a suprise for me, because I thought the update should run smoothly, but the installer removed the previous version and I couldn’t update, because our SQL Server was still on SQL Server 2016. Fortunately we had a VM backup and could rollback to the previous version.

\n\n

Step for Step

\n\n

The update process itself was straightforward: Download the installer and run it.

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

The screenshots are from two different sessions. If you look carefully on the clock you might see that the date is different, that is because of the SQL Server 2016 problem.

\n\n

As you can see - everything worked as expected, but after we updated the server the search, which is powered by ElasticSearch was not working. The “ElasticSearch”-Windows-Service just crashed on startup and I’m not a Java guy, so… we fixed it by removing the search feature and reinstall it. \nWe tried to clean the cache, but it was still not working. After the reinstall of this feature the issue went away.

\n\n

Features

\n\n

Azure Server 2022 is just a minor update (at least from a typical user perspective). The biggest new feature might be “Delivery Plans”, which are nice, but for small teams not a huge benefit. Check out the release notes.

\n\n

A nice - nerdy - enhancement, and not mentioned in the release notes: “mermaid.js” is now supported in the Azure DevOps Wiki, yay!

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/02/15/azure-devops-server-2022-update/","RawContent":null,"Thumbnail":null},{"Title":"Use ASP.NET Core and React with Vite.js","PublishedOn":"2023-02-11T01:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The CRA Problem

\n\n

In my previous post I showed a simple setup with ASP.NET Core & React. The React part was created with the “CRA”-Tooling, which is kind of problematic. The “new” state of the art React tooling seems to be vite.js - so let’s take a look how to use this.

\n\n

\"x\"

\n\n

Step for Step

\n\n

Step 1: Create a “normal” ASP.NET Core project

\n\n

(I like the ASP.NET Core MVC template, but feel free to use something else - same as in the other blogpost)

\n\n

\"x\"

\n\n

Step 2: Install vite.js and init the template

\n\n

Now move to the root directory of your project with a shell and execute this:

\n\n
npm create vite@latest clientapp -- --template react-ts\n
\n\n

This will install the latest & greatest vitejs based react app in a folder called clientapp with the react-ts template (React with Typescript). Vite itself isn’t focused on React and supports many different frontend frameworks.

\n\n

\"x\"

\n\n

Step 3: Enable HTTPS in your vite.js

\n\n

Just like in the “CRA”-setup we need to make sure, that the environment is served under HTTPS. In the “CRA” world we needed to different files from the original ASP.NET Core & React template, but with vite.js there is a much simpler option available.

\n\n

Execute the following command in the clientapp directory:

\n\n
npm install --save-dev vite-plugin-mkcert\n
\n\n

Then in your vite.config.ts use this config:

\n\n
import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport mkcert from 'vite-plugin-mkcert'\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n    base: '/app',\n    server: {\n        https: true,\n        port: 6363\n    },\n    plugins: [react(), mkcert()],\n})\n
\n\n

Be aware: The base: '/app' will be used as a sub-path.

\n\n

The important part for the HTTPS setting is that we use the mkcert() plugin and configure the server part with a port and set https to true.

\n\n

Step 4: Add the Microsoft.AspNetCore.SpaServices.Extensions NuGet package

\n\n

Same as in the other blogpost, we need to add the Microsoft.AspNetCore.SpaServices.Extensions NuGet package to glue the ASP.NET Core development and React world together. If you use .NET 7, then use the version 7.x.x, if you use .NET 6, use the version 6.x.x - etc.

\n\n

\"x\"

\n\n

Step 5: Enhance your Program.cs

\n\n

Back to the Program.cs - this is more or less the same as with the “CRA” setup:

\n\n

Add the SpaStaticFiles to the services collection like this in your Program.cs - be aware, that vite.js builds everything in a folder called dist:

\n\n
var builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\nbuilder.Services.AddControllersWithViews();\n\n// ↓ Add the following lines: ↓\nbuilder.Services.AddSpaStaticFiles(configuration => {\n    configuration.RootPath = \"clientapp/dist\";\n});\n// ↑ these lines ↑\n\nvar app = builder.Build();\n
\n\n

Now we need to use the SpaServices like this:

\n\n
app.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}/{action=Index}/{id?}\");\n\n// ↓ Add the following lines: ↓\nvar spaPath = \"/app\";\nif (app.Environment.IsDevelopment())\n{\n    app.MapWhen(y => y.Request.Path.StartsWithSegments(spaPath), client =>\n    {\n        client.UseSpa(spa =>\n        {\n            spa.UseProxyToSpaDevelopmentServer(\"https://localhost:6363\");\n        });\n    });\n}\nelse\n{\n    app.Map(new PathString(spaPath), client =>\n    {\n        client.UseSpaStaticFiles();\n        client.UseSpa(spa => {\n            spa.Options.SourcePath = \"clientapp\";\n\n            // adds no-store header to index page to prevent deployment issues (prevent linking to old .js files)\n            // .js and other static resources are still cached by the browser\n            spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions\n            {\n                OnPrepareResponse = ctx =>\n                {\n                    ResponseHeaders headers = ctx.Context.Response.GetTypedHeaders();\n                    headers.CacheControl = new CacheControlHeaderValue\n                    {\n                        NoCache = true,\n                        NoStore = true,\n                        MustRevalidate = true\n                    };\n                }\n            };\n        });\n    });\n}\n// ↑ these lines ↑\n\napp.Run();\n
\n\n

Just like in the original blogpost. In the development mode we use the UseProxyToSpaDevelopmentServer-method to proxy all requests to the vite.js dev server. In the real world, we will use the files from the dist folder.

\n\n

Step 6: Invoke npm run build during publish

\n\n

The last step is to complete the setup. We want to build the ASP.NET Core app and the React app, when we use dotnet publish:

\n\n

Add this to your .csproj-file and it should work:

\n\n
\t<PropertyGroup>\n\t\t<SpaRoot>clientapp\\</SpaRoot>\n\t</PropertyGroup>\n\n\t<Target Name=\"PublishRunWebpack\" AfterTargets=\"ComputeFilesToPublish\">\n\t\t<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm install\" />\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm run build\" />\n\n\t\t<!-- Include the newly-built files in the publish output -->\n\t\t<ItemGroup>\n\t\t\t<DistFiles Include=\"$(SpaRoot)dist\\**\" />  <!-- Changed to dist! -->\n\t\t\t<ResolvedFileToPublish Include=\"@(DistFiles->'%(FullPath)')\" Exclude=\"@(ResolvedFileToPublish)\">\n\t\t\t\t<RelativePath>%(DistFiles.Identity)</RelativePath> <!-- Changed! -->\n\t\t\t\t<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n\t\t\t\t<ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n\t\t\t</ResolvedFileToPublish>\n\t\t</ItemGroup>\n\t</Target>\n
\n\n

Result

\n\n

You should now be able to use Visual Studio Code (or something like this) and start the frontend project with dev. If you open a browser and go to https://127.0.0.1:6363/app you should see something like this:

\n\n

\"x\"

\n\n

Now start the ASP.NET Core app and go to /app and it should look like this:

\n\n

\"x\"

\n\n

Ok - this looks broken, right? Well - this is a more or less a “known” problem, but can be easily avoided. If we import the logo from the assets it works as expected and shouldn’t be a general problem:

\n\n

\"x\"

\n\n

Code

\n\n

The sample code can be found here.

\n\n

Video

\n\n

I made a video about this topic (in German, sorry :-/) as well - feel free to subscribe ;)

\n\n\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/02/11/aspnet-core-react-with-vitejs/","RawContent":null,"Thumbnail":null},{"Title":"Use ASP.NET Core & React togehter","PublishedOn":"2023-01-25T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The ASP.NET Core React template

\n\n

\"x\"

\n\n

Visual Studio (at least VS 2019 and the newer 2022) ships with a ASP.NET Core React template, which is “ok-ish”, but has some really bad problems:

\n\n

The React part of this template is scaffolded via “CRA” (which seems to be problematic as well, but is not the point of this post) and uses JavaScript instead of TypeScript.\nAnother huge pain point (from my perspective) is that the template uses some special configurations to just host the react part for users - if you want to mix in some “MVC”/”Razor” stuff, you need to change some of this “magic”.

\n\n

The good parts:

\n\n

Both worlds can live together: During development time the ASP.NET Core stuff is hosted via Kestrel and the React part is hosted under the WebPack Development server. The lovely hot reload is working as expected and is really powerful.\nIf you are doing a release build, the project will take care of the npm-magic.

\n\n

But because of the “bad problems” outweight the benefits, we try to integrate a typical react app in a “normal” ASP.NET Core app.

\n\n

Step for Step

\n\n

Step 1: Create a “normal” ASP.NET Core project

\n\n

(I like the ASP.NET Core MVC template, but feel free to use something else)

\n\n

\"x\"

\n\n

Step 2: Create a react app inside the ASP.NET Core project

\n\n

(For this blogpost I use the “Create React App”-approach, but you can use whatever you like)

\n\n

Execute this in your ASP.NET Core template (node & npm must be installed!):

\n\n
npx create-react-app clientapp --template typescript\n
\n\n

Step 3: Copy some stuff from the React template

\n\n

The react template ships with some scripts and settings that we want to preserve:

\n\n

\"x\"

\n\n

The aspnetcore-https.js and aspnetcore-react.js file is needed to setup the ASP.NET Core SSL dev certificate for the WebPack Dev Server. \nYou should also copy the .env & .env.development file in the root of your clientapp-folder!

\n\n

The .env file only has this setting:

\n\n
BROWSER=none\n
\n\n

A more important setting is in the .env.development file (change the port to something different!):

\n\n
PORT=3333\nHTTPS=true\n
\n\n

The port number 3333 and the https=true will be important later, otherwise our setup will not work.

\n\n

Also, add this line to the .env-file (in theory you can use any name - for this sample we keep it spaApp):

\n\n
PUBLIC_URL=/spaApp\n
\n\n

Step 4: Add the prestart to the package.json

\n\n

In your project open the package.json and add the prestart-line like this:

\n\n
  \"scripts\": {\n    \"prestart\": \"node aspnetcore-https && node aspnetcore-react\",\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\"\n  },\n
\n\n

Step 5: Add the Microsoft.AspNetCore.SpaServices.Extensions NuGet package

\n\n

\"x\"

\n\n

We need the Microsoft.AspNetCore.SpaServices.Extensions NuGet-package. If you use .NET 7, then use the version 7.x.x, if you use .NET 6, use the version 6.x.x - etc.

\n\n

Step 6: Enhance your Program.cs

\n\n

Add the SpaStaticFiles to the services collection like this in your Program.cs:

\n\n
var builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\nbuilder.Services.AddControllersWithViews();\n\n// ↓ Add the following lines: ↓\nbuilder.Services.AddSpaStaticFiles(configuration => {\n    configuration.RootPath = \"clientapp/build\";\n});\n// ↑ these lines ↑\n\nvar app = builder.Build();\n
\n\n

Now we need to use the SpaServices like this:

\n\n
app.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}/{action=Index}/{id?}\");\n\n// ↓ Add the following lines: ↓\nvar spaPath = \"/spaApp\";\nif (app.Environment.IsDevelopment())\n{\n    app.MapWhen(y => y.Request.Path.StartsWithSegments(spaPath), client =>\n    {\n        client.UseSpa(spa =>\n        {\n            spa.UseProxyToSpaDevelopmentServer(\"https://localhost:3333\");\n        });\n    });\n}\nelse\n{\n    app.Map(new PathString(spaPath), client =>\n    {\n        client.UseSpaStaticFiles();\n        client.UseSpa(spa => {\n            spa.Options.SourcePath = \"clientapp\";\n\n            // adds no-store header to index page to prevent deployment issues (prevent linking to old .js files)\n            // .js and other static resources are still cached by the browser\n            spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions\n            {\n                OnPrepareResponse = ctx =>\n                {\n                    ResponseHeaders headers = ctx.Context.Response.GetTypedHeaders();\n                    headers.CacheControl = new CacheControlHeaderValue\n                    {\n                        NoCache = true,\n                        NoStore = true,\n                        MustRevalidate = true\n                    };\n                }\n            };\n        });\n    });\n}\n// ↑ these lines ↑\n\napp.Run();\n
\n\n

As you can see, we run in two different modes. \nIn our development world we just use the UseProxyToSpaDevelopmentServer-method to proxy all requests that points to spaApp to the React WebPack DevServer (or something else). The huge benefit is, that you can use the React ecosystem with all its tools. Normally we use Visual Studio Code to run our react frontend and use the ASP.NET Core app as the “Backend for frontend”.\nIn production we use the build artefacts of the react build and make sure, that it’s not cached. To make the deployment easier, we need to invoke npm run build when we publish this ASP.NET Core app.

\n\n

Step 7: Invoke npm run build during publish

\n\n

Add this to your .csproj-file and it should work:

\n\n
\t<PropertyGroup>\n\t\t<SpaRoot>clientapp\\</SpaRoot>\n\t</PropertyGroup>\n\n\t<Target Name=\"PublishRunWebpack\" AfterTargets=\"ComputeFilesToPublish\">\n\t\t<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm install\" />\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm run build\" />\n\n\t\t<!-- Include the newly-built files in the publish output -->\n\t\t<ItemGroup>\n\t\t\t<DistFiles Include=\"$(SpaRoot)build\\**\" />\n\t\t\t<ResolvedFileToPublish Include=\"@(DistFiles->'%(FullPath)')\" Exclude=\"@(ResolvedFileToPublish)\">\n\t\t\t\t<RelativePath>%(DistFiles.Identity)</RelativePath> <!-- Changed! -->\n\t\t\t\t<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n\t\t\t\t<ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n\t\t\t</ResolvedFileToPublish>\n\t\t</ItemGroup>\n\t</Target>\n
\n\n

Be aware that these instruction are copied from the original ASP.NET Core React template and are slightly modified, otherwise the path wouldn’t match.

\n\n

Result

\n\n

With this setup you can add any spa app that you would like to add to your “normal” ASP.NET Core project.

\n\n

If everything works as expected you should be able to start the React app in Visual Studio Code like this:

\n\n

\"x\"

\n\n

Be aware of the https://localhost:3333/spaApp. The port and the name is important for our sample!

\n\n

Start your hosting ASP.NET Core app in Visual Studio (or in any IDE that you like) and all requests that points to spaApp use the WebPack DevServer in the background:

\n\n

\"x\"

\n\n

With this setup you can mix all client & server side styles as you like - mission succeeded and you can use any client setup (CRA, anything else) as you would like to.

\n\n

Code

\n\n

The code (but with slightly modified values (e.g. another port)) can be found here. \nBe aware, that npm i needs to be run first.

\n\n

Video

\n\n

I uploaded a video on my YouTube channel (in German) about this setup:

\n\n\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/01/25/aspnet-core-and-react/","RawContent":null,"Thumbnail":null},{"Title":"Your URL is flagged as malware/phishing, now what?","PublishedOn":"2023-01-04T22:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Problem

\n\n

On my last day in 2022 - Friday, 23. December, I received a support ticket from one customer, that our software seems to be offline and it looks like that our servers are not responding. I checked our monitoring and the server side of the customer and everything was fine. \nMy first thought: Maybe a misconfiguration on the customer side, but after a remote support session with the customer, I saw that it “should work”, but something in the customer network blocks the requests to our services.\nNext thought: Firewall or proxy stuff. Always nasty, but we are just using port 443, so nothing too special.

\n\n

After a while I received a phone call from the customers firewall team and they discovered the problem: They are using a firewall solution from “Check Point” and our domain was flagged as “phishing”/”malware”. What the… \nThey even created an exception so that Check Point doesn’t block our requests, but the next problem occured: The customers “Windows Defender for Office 365” has the same “flag” for our domain, so they revert everything, because they didn’t want to change their settings too much.

\n\n

\"x\"

\n\n

Be aware, that from our end everything was working “fine” and I could access the customer services and our Windows Defender didn’t had any problems with this domain.

\n\n

Solution

\n\n

Somehow our domain was flagged as malware/phishing and we needed to change this false positive listening. I guess there are tons of services, that “tracks” “bad” websites and maybe all are connected somehow. From this indicent I can only suggest:

\n\n

If you have trouble with Check Point:

\n\n

Go to “URLCAT”, register an account and try to change the category of your domain. After you submit the “change request” you will get an email like this:

\n\n
Thank you for submitting your category change request.\nWe will process your request and notify you by email (to: xxx.xxx@xxx.com ).\nYou can follow the status of your request on this page.\nYour request details\nReference ID: [GUID]\nURL: https://[domain].com\nSuggested Categories: Computers / Internet,Business / Economy\nComment: [Given comment]\n
\n\n

After ~1-2 days the change was done. Not sure if this is automated or not, but it was during Christmas.

\n\n

If you have trouble with Windows Defender:

\n\n

Go to “Report submission” in your Microsoft 365 Defender setting (you will need an account with special permissions, e.g. global admin) and add the URL as “Not junk”.

\n\n

\"x\"

\n\n

I’m not really sure if this helped or not, because we didn’t had any issues with the domain itself and I’m not sure if those “false positive” tickets bubbles up into a “global defender catalog” or if this only affects our own tenant.

\n\n

Result

\n\n

Anyway - after those tickets were “resolved” by Check Point / Microsoft the problem on the customer side disappeared and everyone was happy. This was my first experience with such an “false positive malware report”. I’m not sure how we ended up on such a list and why only one customer was affected.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/01/04/checkpoint-and-defender-false-positive-url/","RawContent":null,"Thumbnail":null},{"Title":"SQLLocalDb update","PublishedOn":"2022-12-03T22:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Short Intro

\n\n

SqlLocalDb is a “developer” SQL server, without the “full” SQL Server (Express) installation. If you just develop on your machine and don’t want to run a “full blown” SQL Server, this is the tooling that you might need.

\n\n

From the Microsoft Docs:

\n\n
\n

Microsoft SQL Server Express LocalDB is a feature of SQL Server Express targeted to developers. It is available on SQL Server Express with Advanced Services.

\n\n

LocalDB installation copies a minimal set of files necessary to start the SQL Server Database Engine. Once LocalDB is installed, you can initiate a connection using a special connection string. When connecting, the necessary SQL Server infrastructure is automatically created and started, enabling the application to use the database without complex configuration tasks. Developer Tools can provide developers with a SQL Server Database Engine that lets them write and test Transact-SQL code without having to manage a full server instance of SQL Server.

\n
\n\n

Problem

\n\n

(I’m not really sure, how I ended up on this problem, but I after I solved the problem I did it on my “To Blog”-bucket list)

\n\n

From time to time there is a new SQLLocalDb version, but to upgrade an existing installation is a bit “weird”.

\n\n

Solution

\n\n

If you have installed an older SQLLocalDb version you can manage it via sqllocaldb. If you want to update you must delete the “current” MSSQLLocalDB in the first place.

\n\n

To to this use:

\n\n
sqllocaldb stop MSSQLLocalDB\nsqllocaldb delete MSSQLLocalDB\n
\n\n

Then download the newest version from Microsoft. \nIf you choose “Download Media” you should see something like this:

\n\n

\"x\"

\n\n

Download it, run it and restart your PC, after that you should be able to connect to the SQLLocalDb.

\n\n

We solved this issue with help of this blogpost.

\n\n

Hope this helps! (and I can remove it now from my bucket list \\o/ )

\n","Href":"https://blog.codeinside.eu/2022/12/03/sqllocaldb-update/","RawContent":null,"Thumbnail":null},{"Title":"Azure DevOps & Azure Service Connection","PublishedOn":"2022-10-04T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Today I needed to setup a new release pipeline on our Azure DevOps Server installation to deploy some stuff automatically to Azure. The UI (at least on the Azure DevOps Server 2020 (!)) is not really clear about how to connect those two worlds, and thats why I’m writing this short blogpost.

\n\n

First - under project settings - add a new service connection. Use the Azure Resource Manager-service. Now you should see something like this:

\n\n

\"x\"

\n\n

Be aware: You will need to register app inside your Azure AD and need permissions to setup. If you are not able to follow these instructions, you might need to talk to your Azure subscription owner.

\n\n

Subscription id:

\n\n

Copy here the id of your subscription. This can be found in the subscription details:

\n\n

\"x\"

\n\n

Keep this tab open, because we need it later!

\n\n

Service prinipal id/key & tenant id:

\n\n

Now this wording about “Service principal” is technically correct, but really confusing if your are not familar with Azure AD. A “Service prinipal” is like a “service user”/”app” that you need to register to use it.\nThe easiest route is to create an app via the Bash Azure CLI:

\n\n
az ad sp create-for-rbac --name DevOpsPipeline\n
\n\n

If this command succeeds you should see something like this:

\n\n
{\n  \"appId\": \"[...GUID..]\",\n  \"displayName\": \"DevOpsPipeline\",\n  \"password\": \"[...PASSWORD...]\",\n  \"tenant\": \"[...Tenant GUID...]\"\n}\n
\n\n

This creates an “Serivce principal” with a random password inside your Azure AD. The next step is to give this “Service principal” a role on your subscription, because it has currently no permissions to do anything (e.g. deploy a service etc.).

\n\n

Go to the subscription details page and then to Access control (IAM). There you can add your “DevOpsPipeline”-App as “Contributor” (Be aware that this is a “powerful role”!).

\n\n

After that use the \"appId\": \"[...GUID..]\" from the command as Service Principal Id. \nUse the \"password\": \"[...PASSWORD...]\" as Service principal key and the \"tenant\": \"[...Tenant GUID...]\" for the tenant id.

\n\n

Now you should be able to “Verify” this connection and it should work.

\n\n

Links:\nThis blogpost helped me a lot. Here you can find the official documentation.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/10/04/azure-devops-azure-service-connection/","RawContent":null,"Thumbnail":null},{"Title":"'error MSB8011: Failed to register output.' & UTF8-BOM files","PublishedOn":"2022-08-30T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Be aware: I’m not a C++ developer and this might be an “obvious” problem, but it took me a while to resolve this issue.

\n\n

In our product we have very few C++ projects. We use these projects for very special Microsoft Office COM stuff and because of COM we need to register some components during the build. Everything worked as expected, but we renamed a few files and our build broke with:

\n\n
C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\MSBuild\\Microsoft\\VC\\v170\\Microsoft.CppCommon.targets(2302,5): warning MSB3075: The command \"regsvr32 /s \"C:/BuildAgentV3_1/_work/67/s\\_Artifacts\\_ReleaseParts\\XXX.Client.Addin.x64-Shims\\Common\\XXX.Common.Shim.dll\"\" exited with code 5. Please verify that you have sufficient rights to run this command. [C:\\BuildAgentV3_1\\_work\\67\\s\\XXX.Common.Shim\\XXX.Common.Shim.vcxproj]\nC:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\MSBuild\\Microsoft\\VC\\v170\\Microsoft.CppCommon.targets(2314,5): error MSB8011: Failed to register output. Please try enabling Per-user Redirection or register the component from a command prompt with elevated permissions. [C:\\BuildAgentV3_1\\_work\\67\\s\\XXX.Common.Shim\\XXX.Common.Shim.vcxproj]\n\n(xxx = redacted)\n
\n\n

The crazy part was: Using an older version of our project just worked as expected, but all changes were “fine” from my point of view.

\n\n

After many, many attempts I remembered that our diff tool doesn’t show us everything - so I checked the file encodings: UTF8-BOM

\n\n

Somehow if you have a UTF8-BOM encoded file that your C++ project uses to register COM stuff it will fail. I changed the encoding and to UTF8 and everyting worked as expected.

\n\n

What a day… lessons learned: Be aware of your file encodings.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/08/30/error-msb8011-failed-to-register-output-and-utf8bom/","RawContent":null,"Thumbnail":null},{"Title":"Which .NET Framework Version is installed on my machine?","PublishedOn":"2022-08-29T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If you need to know which .NET Framework Version (the “legacy” .NET Framework) is installed on your machine try this handy oneliner:

\n\n
Get-ItemProperty \"HKLM:SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\"\n
\n\n

Result:

\n\n
CBS           : 1\nInstall       : 1\nInstallPath   : C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\\nRelease       : 528372\nServicing     : 0\nTargetVersion : 4.0.0\nVersion       : 4.8.04084\nPSPath        : Microsoft.PowerShell.Core\\Registry::HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework\n                Setup\\NDP\\v4\\Full\nPSParentPath  : Microsoft.PowerShell.Core\\Registry::HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\nPSChildName   : Full\nPSDrive       : HKLM\nPSProvider    : Microsoft.PowerShell.Core\\Registry\n
\n\n

The version should give you more then enough information.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/08/29/which-dotnet-version-is-installed-via-powershell/","RawContent":null,"Thumbnail":null},{"Title":"How to run a Azure App Service WebJob with parameters","PublishedOn":"2022-07-22T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We are using WebJobs in our Azure App Service deployment and they are pretty “easy” for the most part. Just register a WebJobs or deploy your .exe/.bat/.ps1/... under the \\site\\wwwroot\\app_data\\Jobs\\triggered folder and it should execute as described in the settings.job.

\n\n

\"x\"

\n\n

If you put any executable in this WebJob folder, it will be executed as planned.

\n\n

Problem: Parameters

\n\n

If you have a my-job.exe, then this will be invoked from the runtime. But what if you need to invoke it with a parameter like my-job.exe -param \"test\"?

\n\n

Solution: run.cmd

\n\n

The WebJob environment is “greedy” and will search for a run.cmd (or run.exe) and if this is found, it will be executed and it doesn’t matter if you have any other .exe files there.\nStick to the run.cmd and use this to invoke your actual executable like this:

\n\n
echo \"Invoke my-job.exe with parameters - Start\"\n\n..\\MyJob\\my-job.exe -param \"test\"\n\necho \"Invoke my-job.exe with parameters - Done\"\n
\n\n

Be aware, that the path must “match”. We use this run.cmd-approach in combination with the is_in_place-option (see here) and are happy with the results).

\n\n

A more detailed explanation can be found here.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/07/22/how-to-run-a-azure-appservice-webjob-with-parameters/","RawContent":null,"Thumbnail":null},{"Title":"How to use IE proxy settings with HttpClient","PublishedOn":"2022-03-28T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Internet Explorer is - mostly - dead, but some weird settings are still around and “attached” to the old world, at least on Windows 10. \nIf your system administrator uses some advanced proxy settings (e.g. a PAC-file), those will be attached to the users IE setting.

\n\n

If you want to use this with a HttpClient you need to code something like this:

\n\n
    string target = \"https://my-target.local\";\n    var targetUri = new Uri(target);\n    var proxyAddressForThisUri = WebRequest.GetSystemWebProxy().GetProxy(targetUri);\n    if (proxyAddressForThisUri == targetUri)\n    {\n        // no proxy needed in this case\n        _httpClient = new HttpClient();\n    }\n    else\n    {\n        // proxy needed\n        _httpClient = new HttpClient(new HttpClientHandler() { Proxy = new WebProxy(proxyAddressForThisUri) { UseDefaultCredentials = true } });\n    }\n
\n\n

The GetSystemWebProxy() gives access to the system proxy settings from the current user. Then we can query, what proxy is needed for the target. If the result is the same address as the target, then no proxy is needed. Otherwise, we inject a new WebProxy for this address.

\n\n

Hope this helps!

\n\n

Be aware: Creating new HttpClients is (at least in a server environment) not recommended. Try to reuse the same HttpClient instance!

\n\n

Also note: The proxy setting in Windows 11 are now built into the system settings, but the API still works :)

\n\n

\"x\"

\n","Href":"https://blog.codeinside.eu/2022/03/28/how-to-use-ie-proxy-settings-with-httpclient/","RawContent":null,"Thumbnail":null},{"Title":"Redirect to HTTPS with a simple web.config rule","PublishedOn":"2022-01-05T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The scenario is easy: My website is hosted in an IIS and would like to redirect all incomming HTTP traffic to the HTTPS counterpart.

\n\n

This is your solution - a “simple” rule:

\n\n
<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n    <system.webServer>\n        <rewrite>\n            <rules>\n                <rule name=\"Redirect to https\" stopProcessing=\"true\">\n                    <match url=\".*\" />\n                    <conditions logicalGrouping=\"MatchAny\">\n                        <add input=\"{HTTPS}\" pattern=\"off\" />\n                    </conditions>\n                    <action type=\"Redirect\" url=\"https://{HTTP_HOST}{REQUEST_URI}\" redirectType=\"Found\" />\n                </rule>\n            </rules>\n        </rewrite>\n    </system.webServer>\n</configuration>\n
\n\n

We used this in the past to setup a “catch all” web site in an IIS that redirects all incomming HTTP traffic.\nThe actual web applications had only the HTTPS binding in place.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/01/05/redirect-to-https-with-a-simple-webconfig-rule/","RawContent":null,"Thumbnail":null},{"Title":"Select random rows","PublishedOn":"2021-12-06T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Let’s say we have a SQL table and want to retrieve 10 rows randomly - how would you do that? Although I have been working with SQL for x years, I have never encountered that problem. The solution however is quite “simple” (at least if you don’t be picky how we define “randomness” and if you try this on millions of rows):

\n\n

ORDER BY NEWID()

\n\n

The most boring way is to use the ORDER BY NEWID() clause:

\n\n
SELECT TOP 10 FROM Products ORDER BY NEWID()\n
\n\n

This works, but if you do that on “large” datasets you might hit performance problems (e.g. more on that here)

\n\n

TABLESAMPE

\n\n

The SQL Server implements the Tablesample clause which was new to me. It seems to perform much bettern then the ORDER BY NEWID() clause, but behaves a bit weird. With this clause you can specify the “sample” from a table. The size of the sample can be specified as PERCENT or ROWS (which are then converted to percent internally).

\n\n

Syntax:

\n\n
SELECT TOP 10 FROM Products TABLESAMPLE (25 Percent)\nSELECT TOP 10 FROM Products TABLESAMPLE (100 ROWS)\n
\n\n

The weird part is that the given number might not match the number of rows of your result. You might got more or less results and if our tablesample is too small you might even got nothing in return. There are some clever ways to work around this (e.g. using the TOP 100 statement with a much larger tablesample clause to get a guaranteed result set), but it feels “strange”.\nIf you hit limitations with the first solution you might want to read more on this blog or in the Microsoft Docs.

\n\n

Stackoverflow

\n\n

Of course there is a great Stackoverflow thread with even wilder solutions.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/12/06/select-random-rows/","RawContent":null,"Thumbnail":null}],"ResultType":"Feed"},"YouTube":{"FeedItems":[{"Title":"Erste Schritte mit dem Azure OpenAI Service","PublishedOn":"2023-03-23T22:30:48+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=VVNHT4gVxDo","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/VVNHT4gVxDo/hqdefault.jpg"},{"Title":"Erster Schritt in die Source Control: Visual Studio Projekte auf GitHub pushen","PublishedOn":"2023-03-17T21:59:57+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=iKQS5nYbC-k","RawContent":null,"Thumbnail":"https://i2.ytimg.com/vi/iKQS5nYbC-k/hqdefault.jpg"},{"Title":"Vite.js für React & TypeScript für ASP.NET Core & Visual Studio Entwickler","PublishedOn":"2023-02-12T00:25:03+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=-2iiXpBcmDY","RawContent":null,"Thumbnail":"https://i2.ytimg.com/vi/-2iiXpBcmDY/hqdefault.jpg"},{"Title":"React.js mit TypeScript in ASP.NET Core mit Visual Studio & Visual Studio Code","PublishedOn":"2023-01-26T23:35:26+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=IgW79wxMO-c","RawContent":null,"Thumbnail":"https://i2.ytimg.com/vi/IgW79wxMO-c/hqdefault.jpg"},{"Title":"React.js mit ASP.NET Core - ein Einstieg mit Visual Studio","PublishedOn":"2022-10-07T23:15:55+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=gIzMtWDs_QM","RawContent":null,"Thumbnail":"https://i4.ytimg.com/vi/gIzMtWDs_QM/hqdefault.jpg"},{"Title":"Einstieg in die Webentwicklung mit .NET 6 & ASP.NET Core","PublishedOn":"2022-04-12T21:13:18+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=WtpzsW5Xwqo","RawContent":null,"Thumbnail":"https://i4.ytimg.com/vi/WtpzsW5Xwqo/hqdefault.jpg"},{"Title":"Das erste .NET 6 Programm","PublishedOn":"2022-01-30T22:21:35+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=fVzo2qJubmA","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/fVzo2qJubmA/hqdefault.jpg"},{"Title":"Azure SQL - ist das echt so teuer? Neee...","PublishedOn":"2022-01-11T21:49:29+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=dNaIOGQj15M","RawContent":null,"Thumbnail":"https://i1.ytimg.com/vi/dNaIOGQj15M/hqdefault.jpg"},{"Title":"Was sind \"Project Templates\" in Visual Studio?","PublishedOn":"2021-12-22T22:36:25+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=_IMabo9yHSA","RawContent":null,"Thumbnail":"https://i4.ytimg.com/vi/_IMabo9yHSA/hqdefault.jpg"},{"Title":".NET Versionen - was bedeutet LTS und Current?","PublishedOn":"2021-12-21T21:06:29+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=2ghTKF0Ey_0","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/2ghTKF0Ey_0/hqdefault.jpg"},{"Title":"Einstieg in die .NET Entwicklung für Anfänger","PublishedOn":"2021-12-20T22:18:35+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=2EcSJDX-8-s","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/2EcSJDX-8-s/hqdefault.jpg"},{"Title":"Erste Schritte mit Unit Tests","PublishedOn":"2008-11-05T00:14:06+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=tjAv1-Qb4rY","RawContent":null,"Thumbnail":"https://i1.ytimg.com/vi/tjAv1-Qb4rY/hqdefault.jpg"},{"Title":"3 Schichten Architektur","PublishedOn":"2008-10-17T22:01:06+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=27yknlB8xeg","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/27yknlB8xeg/hqdefault.jpg"}],"ResultType":"Feed"},"O_Blog":{"FeedItems":[{"Title":"How to build a simple hate speech detector with machine learning","PublishedOn":"2019-08-02T13:00:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"

Not everybody on the internet behaves nice and some comments are just rude or offending. If you run a web page that offers a public comment function hate speech can be a real problem. For example in Germany, you are legally required to delete hate speech comments. This can be challenging if you have to check thousands of comments each day. \nSo wouldn’t it be nice, if you can automatically check the user’s comment and give them a little hint to stay nice?\n

\n\n

The simplest thing you could do is to check if the user’s text contains offensive words. However, this approach is limited since you can offend people without using offensive words.

\n\n

This post will show you how to train a machine learning model that can detect if a comment or text is offensive. And to start you need just a few lines of Python code \\o/

\n\n

The Data

\n\n

At first, you need data. In this case, you will need a list of offensive and nonoffensive texts. I wrote this tutorial for a machine learning course in Germany, so I used German texts but you should be able to use other languages too.

\n\n

For a machine learning competition, scientists provided a list of comments labeled as offensive and nonoffensive (Germeval 2018, Subtask 1). This is perfect for us since we just can use this data.

\n\n

The Code

\n\n

To tackle this task I would first establish a baseline and then improve this solution step by step. Luckily they also published the scores of all submission, so we can get a sense of how well we are doing.

\n\n

For our baseline model we are going to use Facebooks fastText. It’s simple to use, works with many languages and does not require any special hardware like a GPU. Oh, and it’s fast :)

\n\n

1. Load the data

\n\n

After you downloaded the training data file germeval2018.training.txt you need to transform this data into a format that fastText can read.\nFastTexts standard format looks like this “label[your label] some text”:

\n\n
__label__offensive some insults\n__label__other have a nice day\n
\n\n

2. Train the Model

\n\n

To train the model you need to install the fastText Python package.

\n\n
$ pip install fasttext\n
\n

To train the model you need just there line of code.

\n
import fasttext\ntraning_parameters = {'epoch': 50, 'lr': 0.05, 'loss': \"ns\", 'thread': 8, 'ws': 5, 'dim': 100}    \nmodel = fasttext.supervised('fasttext.train', 'model', **traning_parameters)\n
\n\n

I packed all the training parameters into a seperate dictionary. To me that looks a bit cleaner but you don’t need to do that.

\n\n

3. Test your Model

\n\n

After we trained the model it is time to test how it performs. FastText provides us a handy test method the evaluate the model’s performance. To compare our model with the other models from the GermEval contest I also added a lambda which calculates the average F1 score. For now, I did not use the official test script from the contests repository. Which you should do if you wanted to participate in such contests.

\n\n
def test(model):\n    f1_score = lambda precision, recall: 2 * ((precision * recall) / (precision + recall))\n    nexamples, recall, precision = model.test('fasttext.test')\n    print (f'recall: {recall}' )\n    print (f'precision: {precision}')\n    print (f'f1 score: {f1_score(precision,recall)}')\n    print (f'number of examples: {nexamples}')\n
\n\n

I don’t know about you, but I am so curious how we score. Annnnnnnd:

\n\n
recall: 0.7018686296715742\nprecision: 0.7018686296715742\nf1 score: 0.7018686296715742\nnumber of examples: 3532\n
\n\n

Looking at the results we can see that the best other model had an average F1 score of 76,77 and our model achieves -without any optimization and preprocessing- an F1 Score of 70.18.

\n\n

This is pretty good since the models for these contests are usually specially optimized for the given data.

\n\n

FastText is a clever piece of software, that uses some neat tricks. If interested in fastText you should take a look the paper and this one. For example, fastText uses character n-grams. This approach is well suited for the German language, which uses a lot of compound words.

\n\n

Next Steps

\n\n

In this very basic tutorial, we trained a model with just a few lines of Python code. There are several things you can do to improve this model. The first step would be to preprocess your data. During preprocessing you could lower case all texts, remove URLs and special characters, correct spelling, etc. After every optimization step, you can test your model and check if your scores went up. Happy hacking :)

\n\n

Some Ideas:

\n\n
    \n
  1. Preprocess the data
  2. \n
  3. Optimize the parameters (number of training epochs, learning rate, embedding dims, word n-grams)
  4. \n
  5. Use pre-trained word vectors from the fastText website
  6. \n
  7. add more data to the training set
  8. \n
  9. Use data augmentation.
  10. \n
\n\n

Here is the full code:

\n\n\n\n

Credit: Photo by Jon Tyson on Unsplash

","Href":"https://www.oliverguhr.eu/nlp/jekyll/2019/08/02/build-a-simple-hate-speech-detector-with-machine-learning.html","RawContent":null,"Thumbnail":null}],"ResultType":"Feed"},"GitHubEventsUser":{"Events":[{"Id":"42018108069","Type":"IssuesEvent","CreatedAt":"2024-09-17T21:16:23","Actor":"robertmuehsig","Repository":"GregorBiswanger/OllamaApiFacade","Organization":null,"RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/GregorBiswanger/OllamaApiFacade/issues/1","RelatedDescription":"Opened issue \"Create an Open AI compatible facade\" (#1) at GregorBiswanger/OllamaApiFacade","RelatedBody":"Ollama itself is compatible with the [Open AI spec](https://ollama.com/blog/openai-compatibility) and it would be cool to \"embed\" or host an Open AI compatible facade with .NET.\r\n\r\nReason/Goal:\r\n\r\nI want to use the existing Open AI NuGet package and work against a local hosted LLM. There are some ideas in the [LLamaSharp](https://github.com/SciSharp/LLamaSharp/issues/269) repo, but it seems to be tricky. \r\n\r\nYour project looks promising ;)"},{"Id":"41628817944","Type":"IssuesEvent","CreatedAt":"2024-09-04T18:05:32","Actor":"robertmuehsig","Repository":"sangyuxiaowu/LLamaWorker","Organization":null,"RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/sangyuxiaowu/LLamaWorker/issues/23","RelatedDescription":"Opened issue \"Configuration Guide - running in an error while streaming\" (#23) at sangyuxiaowu/LLamaWorker","RelatedBody":"Hi,\r\nI was looking for a combination of LlamaSharp and the OpenAI REST API and this project looks promising.\r\n\r\nMy \"basic need\" would be to simulate the OpenAI REST API like LM Studio did. All I want is to load the Phi3 model and be done.\r\n![image](https://github.com/user-attachments/assets/80ea0488-199d-4bf5-9ee2-f9c9ef499235)\r\n\r\nNow my question: I just changed the paths and deleted the other models in the appsettings, but I wonder: Which properties are \"important\" and what does each setting do?\r\n\r\nMy setting now looks like this - is this \"ok\" or would this break something?\r\n\r\n```\r\n...\r\n \"GlobalSettings\": {\r\n \"CurrentModelIndex\": 0,\r\n // 自动释放时间,分钟。0 表示不自动释放\r\n \"AutoReleaseTime\": 30\r\n },\r\n // LLM 服务配置\r\n \"LLmModelSettings\": [\r\n \r\n {\r\n \"Name\": \"Phi-3-mini-4k-instruct-q4\",\r\n \"Description\": \"The Phi-3-Mini-4K-Instruct is a 3.8B parameters, lightweight, state-of-the-art open model trained with the Phi-3 datasets that includes both synthetic data and the filtered publicly available websites data with a focus on high-quality and reasoning dense properties.\",\r\n \"WebSite\": \"https://www.modelscope.cn/models/sangsq/Phi-3-mini-4k-instruct-gguf\",\r\n \"Version\": \"2024-07-08\",\r\n \"SystemPrompt\": \"You are a helpful AI assistant.\",\r\n \"ModelParams\": {\r\n \"ModelPath\": \"C:\\\\Users\\\\muehsig\\\\.cache\\\\lm-studio\\\\models\\\\lmstudio-community\\\\Phi-3.1-mini-128k-instruct-GGUF\\\\Phi-3.1-mini-128k-instruct-Q4_K_M.gguf\",\r\n \"ContextSize\": 4096,\r\n \"Seed\": 1337,\r\n \"GpuLayerCount\": 20\r\n },\r\n \"AntiPrompts\": [ \"<|user|>\", \"<|end|>\", \"<|endoftext|>\" ],\r\n \"WithTransform\": {\r\n \"HistoryTransform\": \"LLamaWorker.Transform.ZephyrHistoryTransform\"\r\n },\r\n \"ToolPrompt\": {\r\n \"Index\": 0,\r\n \"Lang\": \"en\"\r\n }\r\n }\r\n ],\r\n...\r\n```\r\n\r\nI also received an error with this code:\r\n\r\n```\r\n\r\nChatClient client = new(model: \"???\", \"xlm-qweqweqweW\",\r\n new OpenAI.OpenAIClientOptions()\r\n { Endpoint = new Uri(\"http://localhost:5114/v1\") });\r\n\r\nAsyncCollectionResult updates\r\n = client.CompleteChatStreamingAsync(\"Schreib eine Kindergeschichte mit 8 Sätzen.\");\r\n\r\nConsole.WriteLine($\"[ASSISTANT]:\");\r\nawait foreach (StreamingChatCompletionUpdate update in updates)\r\n{\r\n foreach (ChatMessageContentPart updatePart in update.ContentUpdate)\r\n {\r\n Console.Write(updatePart.Text);\r\n }\r\n}\r\n```\r\n\r\nThe very same code works without any issus when running against the LM Studio - has this something to do with those settings or is there an error in the OpenAI API implementation?\r\n\r\n![image](https://github.com/user-attachments/assets/0605e186-8bf9-4f3e-8b80-dbc2a88e6560)\r\n\r\nException:\r\n\r\n```\r\nSystem.NullReferenceException\r\n HResult=0x80004003\r\n Message=Object reference not set to an instance of an object.\r\n Source=OpenAI\r\n StackTrace:\r\n at OpenAI.Chat.StreamingChatCompletionUpdate.get_ContentUpdate()\r\n at Program.<
$>d__0.MoveNext() in C:\\Users\\muehsig\\source\\repos\\LlmTestApp\\LlmTestApp\\Program.cs:line 44\r\n```\r\n"}],"ResultType":"GitHubEvent"}},"RunOn":"2024-11-13T05:30:02.407197Z","RunDurationInMilliseconds":1574} \ No newline at end of file +{"Data":{"Blog":{"FeedItems":[{"Title":"OpenAI API, LM Studio and Ollama","PublishedOn":"2024-09-17T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

I had the opportunity to attend the .NET User Group Dresden at the beginning of September for the exciting topic “Using Open Source LLMs” and learned a couple of things.

\n\n

How to choose an LLM?

\n\n

There are tons of LLMs (= Large Language Models) that can be used, but which one should we choose? There is no general answer to that - of course - but there is a Chatbot Arena Leaderboard, which measures the “cleverness” between those models. Be aware of the license of each model.

\n\n

There is also a HuggingChat, where you can pick some models and experiment with them.

\n\n

For your first steps on your local hardware: Phi3 does a good job and is not a huge model.

\n\n

LM Studio

\n\n

Ok, you have a model and an idea, but how to play with it on your local machine?

\n\n

The best tool for such a job is: LM Studio.

\n\n

The most interesting part was (and this was “new” to me), that you run those local models in an local, OpenAI compatible (!!!) server.

\n\n

\"x\"

\n\n

OpenAI Compatible server?!

\n\n

If you want to experiment with a lightweight model on your system and interact with it, then it is super handy, if you can use the standard OpenAI client and just run against your local “OpenAI”-like server.

\n\n

Just start the server, use the localhost endpoint and you can use a code like this:

\n\n
using OpenAI.Chat;\nusing System.ClientModel;\n\nChatClient client = new(model: \"model\", \"key\",\n        new OpenAI.OpenAIClientOptions()\n        { Endpoint = new Uri(\"http://localhost:1234/v1\") });\n\nChatCompletion chatCompletion = client.CompleteChat(\n    [\n        new UserChatMessage(\"Say 'this is a test.'\"),\n    ]);\n\nConsole.WriteLine(chatCompletion.Content[0].Text);\n
\n\n

The model and the key don’t seem to matter that much (or at least I worked on my machine). The localhost:1234 service is hosted by LM Studio on my machine. The actual model can be configured in LM Studio and there is a huge choice available.

\n\n

Even streaming is supported:

\n\n
AsyncCollectionResult<StreamingChatCompletionUpdate> updates\n    = client.CompleteChatStreamingAsync(\"Write a short story about a pirate.\");\n\nConsole.WriteLine($\"[ASSISTANT]:\");\nawait foreach (StreamingChatCompletionUpdate update in updates)\n{\n    foreach (ChatMessageContentPart updatePart in update.ContentUpdate)\n    {\n        Console.Write(updatePart.Text);\n    }\n}\n
\n\n

Ollama

\n\n

The obvious next question is: How can I run my own LLM on my own server? LM Studio works fine, but it’s just a development tool.

\n\n

One answer could be: Ollama, which can run large language models and has a compatibility to the OpenAI API.

\n\n

Is there an Ollama for .NET devs?

\n\n

Ollama looks cool, but I was hoping to find an “OpenAI compatible .NET facade”. I already played with LLamaSharp, but LLamaSharp doesn’t offer currently a WebApi, but there are some ideas around. \nMy friend Gregor Biswanger released OllamaApiFacade, which looks promising, but at least it doesn’t offer a real OpenAI compatible .NET facade, but maybe this will be added in the future.

\n\n

Acknowledgment

\n\n

Thanks to the .NET User Group for hosting the meetup, and a special thanks to my good friend Oliver Guhr, who was also the speaker!

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/09/17/openai-api-lmstudio-ollama/","RawContent":null,"Thumbnail":null},{"Title":"Entity Framework Core 8.0 Breaking Changes & SQL Compatibility Level","PublishedOn":"2024-09-08T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We recently switched from .NET 6 to .NET 8 and encountered the following Entity Framework Core error:

\n\n
Microsoft.Data.SqlClient.SqlException: 'Incorrect syntax near the keyword 'WITH'....\n
\n\n

The EF code uses the Contains method as shown below:

\n\n
var names = new[] { \"Blog1\", \"Blog2\" };\n\nvar blogs = await context.Blogs\n    .Where(b => names.Contains(b.Name))\n    .ToArrayAsync();\n
\n\n

Before .NET 8 this would result in the following Sql statement:

\n\n
SELECT [b].[Id], [b].[Name]\nFROM [Blogs] AS [b]\nWHERE [b].[Name] IN (N'Blog1', N'Blog2')\n
\n\n

… and with .NET 8 it uses the OPENJSON function, which is not supported on older versions like SQL Server 2014 or if the compatibility level is below 130 (!)

\n\n\n\n

The fix is “simple”

\n\n

Ensure you’re not using an unsupported SQL version and that the Compatibility Level is at least on level 130.

\n\n

If you can’t change the system, then you could also enforce the “old” behavior with a setting like this (not recommended, because it is slower!)

\n\n
...\n.UseSqlServer(@\"<CONNECTION STRING>\", o => o.UseCompatibilityLevel(120));\n
\n\n

How to make sure your database is on Compatibility Level 130?

\n\n

Run this statement to check the compatibility level:

\n\n
SELECT name, compatibility_level FROM sys.databases;\n
\n\n

We updated our test/dev SQL Server and then moved all databases to the latest version with this SQL statement:

\n\n
DECLARE @DBName NVARCHAR(255)\nDECLARE @SQL NVARCHAR(MAX)\n\n-- Cursor to loop through all databases\nDECLARE db_cursor CURSOR FOR\nSELECT name\nFROM sys.databases\nWHERE name NOT IN ('master', 'tempdb', 'model', 'msdb') -- Exclude system databases\n\nOPEN db_cursor\nFETCH NEXT FROM db_cursor INTO @DBName\n\nWHILE @@FETCH_STATUS = 0\nBEGIN\n    -- Construct the ALTER DATABASE command\n    SET @SQL = 'ALTER DATABASE [' + @DBName + '] SET COMPATIBILITY_LEVEL = 150;'\n    EXEC sp_executesql @SQL\n\n    FETCH NEXT FROM db_cursor INTO @DBName\nEND\n\nCLOSE db_cursor\nDEALLOCATE db_cursor\n
\n\n

Check EF Core Breaking Changes

\n\n

There are other breaking changes, but only the first one affected us: Breaking Changes

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/09/08/ef-core-8-breaking-changes-and-sql-compatibility-level/","RawContent":null,"Thumbnail":null},{"Title":"Connection Resiliency for Entity Framework Core and SqlClient","PublishedOn":"2024-09-02T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

If you work with SQL Azure you might find this familiar:

\n\n
\n

Unexpected exception occurred: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding ‘EnableRetryOnFailure’ to the ‘UseSqlServer’ call.

\n
\n\n

EF Core Resiliency

\n\n

The above error already shows a very simple attempt to “stabilize” your application. If you are using Entity Framework Core, this could look like this:

\n\n
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)\n{\n    optionsBuilder\n        .UseSqlServer(\n            @\"Server=(localdb)\\mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0\",\n            options => options.EnableRetryOnFailure());\n}\n
\n\n

The EnableRetryOnFailure-Method has a couple of options, like a retry count or the retry delay.

\n\n

If you don’t use the UseSqlServer-method to configure your context, there are other ways to enable this behavior: See Microsoft Docs

\n\n

Microsoft.Data.SqlClient - Retry Provider

\n\n

If you use the “plain” Microsoft.Data.SqlClient NuGet Package to connect to your database have a look at Retry Logic Providers

\n\n

A basic implementation would look like this:

\n\n
// Define the retry logic parameters\nvar options = new SqlRetryLogicOption()\n{\n    // Tries 5 times before throwing an exception\n    NumberOfTries = 5,\n    // Preferred gap time to delay before retry\n    DeltaTime = TimeSpan.FromSeconds(1),\n    // Maximum gap time for each delay time before retry\n    MaxTimeInterval = TimeSpan.FromSeconds(20)\n};\n\n// Create a retry logic provider\nSqlRetryLogicBaseProvider provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);\n\n// Assumes that connection is a valid SqlConnection object \n// Set the retry logic provider on the connection instance\nconnection.RetryLogicProvider = provider;\n// Establishing the connection will retry if a transient failure occurs.\nconnection.Open();\n
\n\n

You can set a RetryLogicProvider on a Connection and on a SqlCommand.

\n\n

Some more links and tips

\n\n

These two options seem to be the “low-level-entry-points”.\nOf course could you wrap each action with a library like Polly.

\n\n

During my research I found a good overview: Implementing Resilient Applications.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/09/02/connection-resiliency-for-ef-core-and-sql-data/","RawContent":null,"Thumbnail":null},{"Title":"UrlEncode the Space Character","PublishedOn":"2024-08-20T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

This might seem trivial, but last week I noticed that the HttpUtility.UrlEncode(string) encodes a space ` ` into +, whereas the JavaScript encodeURI(string) method encodes a space as %20.\nThis brings up the question:

\n\n

Why?

\n\n

It seems that in the early specifications, a space was encoded into a +, see this Wikipedia entry:

\n\n
\n

When data that has been entered into HTML forms is submitted, the form field names and values are encoded and sent to the server in an HTTP request message using method GET or POST, or, historically, via email.[3] The encoding used by default is based on an early version of the general URI percent-encoding rules,[4] with a number of modifications such as newline normalization and replacing spaces with + instead of %20. The media type of data encoded this way is application/x-www-form-urlencoded, and it is currently defined in the HTML and XForms specifications. In addition, the CGI specification contains rules for how web servers decode data of this type and make it available to applications.

\n
\n\n

This convention has persisted to this day. For instance, when you search something on Google or Bing with a space in the query, the space is encoded as a +.

\n\n

There seems to be some rules however, e.g. it is only “allowed” in the query string or as form parameters.

\n\n

I found the question & answers on StackOverflow quite informative, and this answer summarizes it well enough for me:

\n\n
| standard      | +   | %20 |\n|---------------+-----+-----|\n| URL           | no  | yes |\n| query string  | yes | yes |\n| form params   | yes | no  |\n| mailto query  | no  | yes |\n
\n\n

What about .NET?

\n\n

If you want to always encode spaces as %20, use the UrlPathEncode method, see here.

\n\n
\n

You can encode a URL using with the UrlEncode method or the UrlPathEncode method. However, the methods return different results. The UrlEncode method converts each space character to a plus character (+). The UrlPathEncode method converts each space character into the string “%20”, which represents a space in hexadecimal notation. Use the UrlPathEncode method when you encode the path portion of a URL in order to guarantee a consistent decoded URL, regardless of which platform or browser performs the decoding.

\n
\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/08/20/urlencoding-the-space-char/","RawContent":null,"Thumbnail":null},{"Title":"dsregcmd, WAM and 'Connected to Windows'-Accounts","PublishedOn":"2024-08-06T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

I was researching if it is possible to have a “real” single-sign-on experience with Azure AD/Entra ID and third-party desktop applications and I stumbled across a few things during my trip.

\n\n

“Real” SSO?

\n\n

There are a bunch of definitions out there about SSO.\nMost of the time, SSO just means: You can use the same account in different applications.

\n\n

But some argue that a “real” SSO experience should mean: You log in to your Windows Desktop environment, and that’s it - each application should just use the existing Windows account.

\n\n

Problems

\n\n

With “Integrated Windows Auth,” this was quite easy, but with Entra ID, it seems really hard. Even Microsoft seems to struggle with this task, because even Microsoft Teams and Office need at least a hint like an email address to sign in the actual user.

\n\n

Solution?

\n\n

I _didn’t__ found a solution for this (complex) problem, but I found a few interesting tools/links that might help achieve it.

\n\n

Please let me know if you find a solution 😉

\n\n

“dsregcmd”

\n\n

There is a tool called dsregcmd, which stands for “Directory Service Registration” and shows how your device is connected to Azure AD.

\n\n
PS C:\\Users\\muehsig> dsregcmd /?\nDSREGCMD switches\n                        /? : Displays the help message for DSREGCMD\n                   /status : Displays the device join status\n               /status_old : Displays the device join status in old format\n                     /join : Schedules and monitors the Autojoin task to Hybrid Join the device\n                    /leave : Performs Hybrid Unjoin\n                    /debug : Displays debug messages\n               /refreshprt : Refreshes PRT in the CloudAP cache\n          /refreshp2pcerts : Refreshes P2P certificates\n          /cleanupaccounts : Deletes all WAM accounts\n             /listaccounts : Lists all WAM accounts\n             /UpdateDevice : Update device attributes to Azure AD\n
\n\n

In Windows 11 - as far as I know - a new command was implemented: /listaccounts

\n\n

dsregcmd /listaccounts

\n\n

This command lists all “WAM” accounts from my current profile:

\n\n

The ...xxxx... is used to hide information

\n\n
PS C:\\Users\\muehsig> dsregcmd /listaccounts\nCall ListAccounts to list WAM accounts from the current user profile.\nUser accounts:\nAccount: u:a17axxxx-xxxx-xxxx-xxxx-1caa2b93xxxx.85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx, user: xxxx.xxxx@xxxx.com, authority: https://login.microsoftonline.com/85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx.\nAccounts found: 1.\nApplication accounts:\nAccounts found: 0.\nDefault account: u:a17axxxx-xxxx-xxxx-xxxx-1caa2b93xxxx.85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx, user: xxxx.xxxx@xxxx.com.\n
\n\n

What is WAM?

\n\n

It’s not the cool x-mas band with the fancy song (that we all love!).

\n\n

WAM stands for Web Account Manager and it integrates with the Windows Email & accounts setting:

\n\n

\"x\"

\n\n

WAM can also be used to obtain a Token - which might be the right direction for my SSO question, but I couldn’t find the time to test this out.

\n\n

“Connected to Windows”

\n\n

This is now pure speculation, because I couldn’t find any information about it, but I think the “Connected to Windows” hint here:

\n\n

\"x\"

\n\n

… is based on the Email & accounts setting (= WAM), and with dsregcmd /listaccounts I can see diagnostic information about it.

\n\n

“Seamless single sign-on”

\n\n

I found this troubleshooting guide and it seems that there is a thing called “seamless single sign-on”, but I’m not 100% sure if this is more a “Development” topic or “IT-Pro” topic (or a mix of both).

\n\n

TIL

\n\n

I (and you!) have learned about a tool called dsregcmd.

\n\n

Try out the dsregcmd /status, it’s like ipconfig /all, but for information about AD connectivity.

\n\n

WAM plays an important part with the “Email & accounts” setting and maybe this is the right direction for the actual SSO topic.

\n\n

Open questions…

\n\n

Some open questions:

\n\n\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/08/06/dsregcmd-wam-and-connected-to-windows-accounts/","RawContent":null,"Thumbnail":null},{"Title":"SQL ConnectionString: Encrypt & Trust Server Certificate","PublishedOn":"2024-07-22T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

\n\n

In our product, we store all data in an MS SQL database. One of our clients had issues with the SQL connection, and I want to share what I learned about SQL Encryption and how (some) properties of the Connection String affect the behavior.

\n\n

Basic SQL Connection String

\n\n

In general, we have a pretty easy setup:

\n\n

Our application reads a typical connection string that looks like this Data Source=your-sql-server.yourcorp.local;Initial Catalog=database_x;User ID=username;Password=password_here;MultipleActiveResultSets=True;Encrypt=False or (for Windows Authentication) Integrated Security=true instead of User ID=username;Password=password_here, and uses the (new) Microsoft.Data.SqlClient to connect to the database.

\n\n

Let’s look at all applied properties:

\n\n\n\n

Since Version 4.0 of the Microsoft.Data.SqlClient the Encrypt property defaults to true instead of false, and now we are entering the field of encryption…

\n\n

Encryption

\n\n

We usally use Encrypt=False, because in most cases, there is no proper certificate installed on the SQL Server - at least this is our experience with our clients. If a client has a proper setup, we recommend using it, of course, but most of the time there is none.

\n\n

With Encrypt=True, the data between the client and the server is TLS encrypted (and this is a good thing, and the breaking change therefore had a good intention).

\n\n

If you are interested how to set it up, this might be a good starting point for you: Configure SQL Server Database Engine for encrypting connections

\n\n

In some cases, your client might not be able to trust the server certificate (e.g. there is just a self-signed cert installed on the SQL server). Then you can disable the certification validation via TrustServerCertification, but this shouldn’t be used (at least in production) or handled with care. If the certificate doesn’t match the name of the Data Source, then you can use HostNameInCertificate.

\n\n

What have I learned?

\n\n

I already knew about Encrypt=True or Encrypt=False, but the behavior of TrustServerCertification (and when to use it) was new for me. This Stackoverflow-question helped me a lot to discover it.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/07/22/sql-connectionstring-encrypt-and-trustservercertificate/","RawContent":null,"Thumbnail":null},{"Title":"LLamaSharp: Run a ChatGPT like system on your hardware for dummies","PublishedOn":"2024-05-15T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

TL;DR summary: Check out the LLamaSharp Quick Start and you will find everything that you need to know

\n\n

ChatGPT (and all those Microsoft Copilots out there that were build on top of this) is currently the synonym for AI based chat systems. As a dev you can just use the Azure OpenAI Services and integrate this in your app - I blogged about this last year.

\n\n

The only “downside” is, that you rely on a cloud system, that costs money and you need to trust the overall system and as a tech nerd it is always “cool” to host stuff yourself.\nOf course, there are a lot of other good reasons why hosting such a system yourself is a good idea, but we just stick with “it is cool” for this blogpost. (There are tons of reasons why this is a stupid idea as well, but we might do it anyway just for fun.)

\n\n

Is there something for .NET devs?

\n\n

My AI knowledge is still quite low and I’m more a “.NET backend developer”, so I was looking for an easy solution for my problem and found “LLamaSharp”.

\n\n

This blogpost and my experiment was inspired by Maarten Balliauws blog post “Running Large Language Models locally – Your own ChatGPT-like AI in C#”, which is already a year old, but still a good intro in this topic.

\n\n

LLamaSharp

\n\n

From their GitHub Repo:

\n\n
\n

LLamaSharp is a cross-platform library to run 🦙LLaMA/LLaVA model (and others) on your local device. Based on llama.cpp, inference with LLamaSharp is efficient on both CPU and GPU. With the higher-level APIs and RAG support, it’s convenient to deploy LLM (Large Language Model) in your application with LLamaSharp.

\n
\n\n

Be aware: This blogpost is written with LLamaSharp version 0.12.0 - Maartens blogpost is based on version 0.3.0 and the model he was using is not working anymore.

\n\n

This sounds really good - let’s checkout the quick start

\n\n

The basic steps are easy: Just add the LLamaSharp and LLamaSharp.Backend.Cpu NuGet package to your project and then search for a model… but where?

\n\n

The model

\n\n

From the quick start:

\n\n
\n

There are two popular format of model file of LLM now, which are PyTorch format (.pth) and Huggingface format (.bin). LLamaSharp uses GGUF format file, which could be converted from these two formats. To get GGUF file, there are two options:

\n\n

Search model name + ‘gguf’ in Huggingface, you will find lots of model files that have already been converted to GGUF format. Please take care of the publishing time of them because some old ones could only work with old version of LLamaSharp.

\n\n

Convert PyTorch or Huggingface format to GGUF format yourself. Please follow the instructions of this part of llama.cpp readme to convert them with the python scripts.

\n\n

Generally, we recommend downloading models with quantization rather than fp16, because it significantly reduce the required memory size while only slightly impact on its generation quality.

\n
\n\n

Okay… I ended up using the huggingface-search-approach and picked the Phi-3-mini-4k-instruct-gguf, because I heard about it somewhere.

\n\n

Code

\n\n

After the initial search and download I could just copy/paste the quick start code in my project and hit run:

\n\n
using LLama.Common;\nusing LLama;\n\nstring modelPath = @\"C:\\temp\\Phi-3-mini-4k-instruct-q4.gguf\"; // change it to your own model path.\n\nvar parameters = new ModelParams(modelPath)\n{\n    ContextSize = 1024, // The longest length of chat as memory.\n    GpuLayerCount = 2 // How many layers to offload to GPU. Please adjust it according to your GPU memory.\n};\nusing var model = LLamaWeights.LoadFromFile(parameters);\nusing var context = model.CreateContext(parameters);\nvar executor = new InteractiveExecutor(context);\n\n// Add chat histories as prompt to tell AI how to act.\nvar chatHistory = new ChatHistory();\nchatHistory.AddMessage(AuthorRole.System, \"Transcript of a dialog, where the User interacts with an Assistant named Bob. Bob is helpful, kind, honest, good at writing, and never fails to answer the User's requests immediately and with precision.\");\nchatHistory.AddMessage(AuthorRole.User, \"Hello, Bob.\");\nchatHistory.AddMessage(AuthorRole.Assistant, \"Hello. How may I help you today?\");\n\nChatSession session = new(executor, chatHistory);\n\nInferenceParams inferenceParams = new InferenceParams()\n{\n    MaxTokens = 256, // No more than 256 tokens should appear in answer. Remove it if antiprompt is enough for control.\n    AntiPrompts = new List<string> { \"User:\" } // Stop generation once antiprompts appear.\n};\n\nConsole.ForegroundColor = ConsoleColor.Yellow;\nConsole.Write(\"The chat session has started.\\nUser: \");\nConsole.ForegroundColor = ConsoleColor.Green;\nstring userInput = Console.ReadLine() ?? \"\";\n\nwhile (userInput != \"exit\")\n{\n    await foreach ( // Generate the response streamingly.\n        var text\n        in session.ChatAsync(\n            new ChatHistory.Message(AuthorRole.User, userInput),\n            inferenceParams))\n    {\n        Console.ForegroundColor = ConsoleColor.White;\n        Console.Write(text);\n    }\n    Console.ForegroundColor = ConsoleColor.Green;\n    userInput = Console.ReadLine() ?? \"\";\n}\n
\n\n

The result is a “ChatGPT-like” chat bot (maybe not so smart, but it runs quick ok-ish on my Dell notebook:

\n\n

\"x\"

\n\n

Summary

\n\n

After some research which model can be used with LLamaSharp it went really smoothly (even for a .NET dummy like me).

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/05/15/llamasharp-run-a-chatgpt-like-system-on-your-hardware-for-dummies/","RawContent":null,"Thumbnail":null},{"Title":"dotnet dev-certs https - How .NET Issues Your Local Dev HTTPS Certificate","PublishedOn":"2024-03-15T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If you start developing a ASP.NET Core application you will notice that your site is running under “http s ://localhost:1234” and that your browser is happy to accept it - so there are some questions to be asked.

\n\n

Why HTTPS on your local dev box?

\n\n

The first question might be: Why is HTTPS on your local dev box even needed?

\n\n

At least two reasons for this (from my perspective):

\n\n\n

I wouldn’t count “security” as an issue here, because you are developing on your own system. If there is something on your machine HTTPS won’t help you at that point.

\n\n

How does ASP.NET Core issues a valid & trusted cert?

\n\n

I’m not exactly sure when this happens, as it was already installed on my development machine.

\n\n

Either when you install the Visual Studio workload for ASP.NET Core or if you create your very first ASP.NET Core application the dev cert for localhost will be issued.

\n\n

But how?

\n\n

The .NET SDK ships with a CLI tool called dotnet dev-certs https and this tool issues the certificate.\nThe output of this command will look like this if a valid and trusted certificate is found::

\n\n
PS C:\\Users\\muehsig> dotnet dev-certs https\nA valid HTTPS certificate is already present.\n
\n\n

dev-certs https

\n\n

There are other options available:

\n\n
PS C:\\Users\\muehsig> dotnet dev-certs https --help\n\n\nUsage: dotnet dev-certs https [options]\n\nOptions:\n  -ep|--export-path  Full path to the exported certificate\n  -p|--password      Password to use when exporting the certificate with the private key into a pfx file or to encrypt the Pem exported key\n  -np|--no-password  Explicitly request that you don't use a password for the key when exporting a certificate to a PEM format\n  -c|--check         Check for the existence of the certificate but do not perform any action\n  --clean            Cleans all HTTPS development certificates from the machine.\n  -i|--import        Imports the provided HTTPS development certificate into the machine. All other HTTPS developer certificates will be cleared out\n  --format           Export the certificate in the given format. Valid values are Pfx and Pem. Pfx is the default.\n  -t|--trust         Trust the certificate on the current platform. When combined with the --check option, validates that the certificate is trusted.\n  -v|--verbose       Display more debug information.\n  -q|--quiet         Display warnings and errors only.\n  -h|--help          Show help information\n
\n\n

What happens when the cert is no longer valid?

\n\n

This is an interesting one, because I had this experience just this week (and that’s the reason for this blogpost).

\n\n

A certificate needs to be in the certification store to be considered trusted. That means your “localhost”-dev cert will be stored in your personal certification store (at least on Windows):

\n\n

\"x\"

\n\n

As you can see, the command dotnet dev-certs https --check --trust will return something like this:

\n\n
A trusted certificate was found: E7A2FB302F26BCFFB7C21801C09081CF2FAAAD2C - CN=localhost - Valid from 2024-03-13 11:12:10Z to 2025-03-13 11:12:10Z - IsHttpsDevelopmentCertificate: true - IsExportable: true\n
\n\n

If the certificate is stale, then your browser won’t accept it anymore and your web application will start, but can’t be viewed because your browser will refuse it.

\n\n

How to repair invalid certificates?

\n\n

Use the two commands and it should work again:

\n\n
dotnet dev-certs https --clean\n
\n\n

…which will remove the old certification and…

\n\n
dotnet dev-certs https --trust\n
\n\n

… to issue a new cert and invoke the trust dialog from Windows.

\n\n

If it works…

\n\n

There are some more options, e.g. to export the certificate, which can be useful in certain scenarios, but if you can use HTTPS on your local development machine and everything works you shouldn’t have to bother.\nIf you want to learn more, checkout the dotnet dev-certs documentation.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/03/15/dotnet-dev-certs-https/","RawContent":null,"Thumbnail":null},{"Title":".NET Upgrade Assistant","PublishedOn":"2024-03-07T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

For those facing the challenge of migrating their .NET Framework-based application to the modern .NET stack, Microsoft’s “Upgrade Assistant” is highly recommended:

\n\n\n\n

What is the “Upgrade Assistant”?

\n\n

The “Upgrade Assistant” is a tool that can integrate into Visual Studio or be accessed via CLI.\nIf you install the extension for Visual Studio you will have a new option “Upgrade project” available in your Solution Explorer.

\n\n

.NET Framework to “new” and more…

\n\n

Its main use case is upgrading .NET Framework-based WPF, WinForms, class libraries, or web applications to the newest .NET version. Besides this, the tool offers some other migration paths as well, e.g. from UWP to WinUI 3.

\n\n

You even can use the tool to migrate from an older .NET Core version to a newer version (but - to be honest: those upgrades are quite easy in contrast to the .NET Framework to .NET Core migration).

\n\n

Depending on the project type, the assistant allows for an “In-Place Upgrade,” “Side-by-Side,” or “Side-by-Side Incremental” upgrade.

\n\n\n\n

You can see those upgrade methods in the video above.

\n\n

Is it good?

\n\n

We have used (or at least tested) the Assistant for upgrading WPF and class libraries to .NET Core and it helps to identify problems (e.g. if a NuGet package or any “old” framework code is not compatible).\nMy verdict: If you need to upgrade your code, you should give it a try.\nIn a more complex code base, it will sometimes mess with the code, but it still helps to give directions.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/03/07/upgrade-assistant/","RawContent":null,"Thumbnail":null},{"Title":"WinUI 3 Community Toolkit and the Template Studio","PublishedOn":"2024-02-24T23:59:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In my last post “First steps with WinUI 3” I already mentioned the “WinUI 3 Gallery”-App, but I missed mentioning two great resources.

\n\n

If you take a deeper look at the “Home” page, you will spot the Community Toolkit Gallery (another app) and the “Template Studio for WinUI”.

\n\n

\"x\"

\n\n

What is the Community Toolkit?

\n\n

The Community Toolkit is a community-driven collection of components and other helpers.

\n\n

\"x\"

\n\n

The “home” of the Community Toolkit can be found on GitHub

\n\n

As of today, the Community Toolkit seems “alive” with recent commits in February 2024.

\n\n

Interesting fact: The controls from the toolkit seems to work with the Uno Platform as well.

\n\n

What is the Template Studio?

\n\n

Template Studio is an addin for Visual Studio and can be installed from the Marketplace.

\n\n

This adds the ‘Template Studio for WinUI’ template to Visual Studio:

\n\n

\"x\"

\n\n

After the usual “pick a name and location” you will be greeted with this Wizard:

\n\n

The first step is to select a “Project type”:

\n\n

\"x\"

\n\n

In the next step you choose a “Design pattern” - which has only one item… well.

\n\n

\"x\"

\n\n

In “Pages” you can create your “views/pages” based on a given layout:

\n\n

Some pages can only be added once (e.g. the “Settings”), but most pages can be added multiple times.

\n\n

\"x\"

\n\n

In “Features” you can add some WinUI 3 related features:

\n\n

\"x\"

\n\n

In the last setting you can decide if you want to add an MSTest project as well:

\n\n

\"x\"

\n\n

The result is the following Visual Studio solution, which includes two projects and a number of TODO items:

\n\n

\"x\"

\n\n

If you run the code a pretty simple app with your configured pages will be found:

\n\n

\"x\"

\n\n

Warning: Such code generators might be a good starting point, but (as always with such generators) the code might be “too stupid” or “too complicated” - depending on your needs.

\n\n

Any other useful resource?

\n\n

I’m a newbie with WinUI 3. The Community Toolkit looks promising and even the Template Studio looks good - at least from a few minutes playtime. If anyone has other useful resource: Please let me know (e.g. in the comments or via email).

\n\n

Hope this helps!

\n\n","Href":"https://blog.codeinside.eu/2024/02/24/winui3-with-community-toolkit-and-template-studio/","RawContent":null,"Thumbnail":null},{"Title":"First steps with WinUI 3","PublishedOn":"2024-02-12T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Developing desktop apps for Windows is quite complex in 2024. There are some “old school” frameworks like WPF or WinForms (or even older stuff) and there is this confusing UWP (but I think it’s dead). \nThe “modern stack” seems to be WinUI - so let’s take a look.

\n\n

\"x\"

\n\n

See here

\n\n

What is WinUI?

\n\n

WinUI is the “modern” version of WPF without the (dumb?) constraints from UWP. You can of course use your typical “Windows” programming languages (like C# or C++).

\n\n

If you heard of UWP. The “Universal Windows Platform” was a good idea but failed, because - at least from my limited testing - the platform was very strict and you couldn’t do the same stuff that you can do with WPF/WinForms.

\n\n

WinUI 1 and 2 were targeted at UWP (if I remember correctly) and with WinUI 3 Microsoft decided to lift those UWP constraints and with it we get a modern desktop stack based on the “known” XAML.

\n\n

In summary:

\n\n

WinUI 3 apps can be used for apps that run on Windows 11 and Windows 10 and can be distributed via the Microsoft Store and you can do the same crazy stuff that you love about WPF/WinForms.

\n\n

Does anybody outside of Microsoft use WinUI?

\n\n

WinUI is used in Windows 11, e.g. the settings or the new explorer - which is nice, but it would be good, if we found a non-Microsoft app that uses this tech, right?

\n\n

Thankfully last week Apple decided to release Apple Music (and other apps) as a native Windows app and it seems (confirmed) like it was written with WinUI:

\n\n

\"x\"

\n\n

If Apple uses this tech, it seems “safe enough” for some exploration.

\n\n

How to get started?

\n\n

You will need Visual Studio 2022. Be aware, that even if you check all those desktop related workloads in the installer the WinUI 3 templates are still missing.

\n\n

\"x\"

\n\n

For the WinUI 3 templates you will need to install the Windows App SDK.

\n\n

Visual Studio Templates

\n\n

After the Windows App SDK is installed we finally have the templates in Visual Studio:

\n\n

\"x\"

\n\n

The default Blank App, Packaged (WinUI 3 in Desktop) is… well… quite blank:

\n\n

\"x\"

\n\n

If you start the application, you will see this:

\n\n

\"x\"

\n\n

Packaged vs. Unpacked

\n\n

If you check the toolbar, you will notice the App 6 (Package) debug button. Packaged Apps can access some Windows APIs (e.g. custom context menu extensions) that Unpackaged Apps can’t. Unpackaged Apps on the other hand act like WPF apps - e.g. they have a “normal” .exe and can be distributed like any .exe-file.

\n\n

This documentation page should cover this topic.

\n\n

Let’s say we want to have a “proper” myApp.exe app, then the Unpackaged App is the way to go. If you choose the App 6 (Unpackaged) debug option you might see this weird error:

\n\n
XamlCheckProcessRequirements();\n\nException Unhandled:\nSystem.DllNotFoundException: 'Unable to load DLL 'Microsoft.ui.xaml.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)'\n
\n\n

To fix this, you will need to add this to the .csproj:

\n\n
\t<PropertyGroup>\n\t\t...\n\t\t<WindowsPackageType>None</WindowsPackageType>\n        ...\n\t</PropertyGroup>\n
\n\n

After that the debug button should start the application and you should be able to start the .exe.

\n\n

Samples

\n\n

Ok, the most basic steps are done - now what?

\n\n

To get a feeling about what is possible and what not, you should install the WinUI 3 Gallery app.

\n\n

\"x\"

\n\n

This application should give a some guidiance.

\n\n

Hope this helps!

\n\n

Note: I’m a beginner with WinUI 3 and just want to show other people the first few steps - if I miss something, just write me a comment! Thanks <3

\n\n","Href":"https://blog.codeinside.eu/2024/02/12/first-steps-with-winui3/","RawContent":null,"Thumbnail":null},{"Title":"How Windows locates an executable via PATH or App Paths","PublishedOn":"2024-01-17T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If you’ve ever worked with the Windows operating system, especially in a programming context, you might have used the Process.Start(yourapp) (e.g. Process.Start(Outlook)) method in languages like C#.\nThis method is used to start a process - essentially to run an executable file. But have you ever stopped to think about how Windows knows where to find the executables you’re trying to run? Let’s dive into the inner workings of Windows and uncover this mystery.

\n\n

Understanding the PATH Environment Variable

\n\n

One of the first things that come into play is the PATH environment variable. This variable is crucial for the operating system to locate the executables.

\n\n

What is the PATH Variable?

\n\n

The PATH environment variable is a system-wide or user-specific setting that lists directories where executable files are stored. When you run a command in the command prompt or use Process.Start(...), Windows looks through these directories to find the executable file.

\n\n

The PATH environment variable can be viewed via the system settings:

\n\n

\"x\"

\n\n

… there is also a nice editor now build into Windows for the PATH environment variable:

\n\n

\"x\"

\n\n

How Does PATH Work?

\n\n

If the executable is not in the current directory, Windows searches through each directory specified in the PATH variable. The order of directories in PATH is important - Windows searches them in the order they are listed. If it finds the executable in one of these directories, it runs it.

\n\n

However, the PATH variable isn’t the only mechanism at play here.

\n\n

The Role of App Paths in the Windows Registry

\n\n

Another less-known but equally important component is the “App Paths” registry key. This key is located in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths.

\n\n

Understanding App Paths

\n\n

The App Paths key is used to specify paths to specific applications. Each application can have its entry under the App Paths key, which means that Windows can find and run these applications even if their directories are not listed in the PATH variable.

\n\n

\"x\"

\n\n

How Do App Paths Work?

\n\n

When you use Process.Start(...) and specify an application name like “OUTLOOK”, Windows first checks the App Paths registry key before it checks the PATH variable. If it finds an entry for the application here, it uses this path to start the application. This is particularly useful for applications that are not in common directories or have multiple executables in different locations.

\n\n

Conclusion

\n\n

Both PATH and App Paths play significant roles. While PATH is great for general-purpose directory searching (especially for system utilities and command-line tools), App Paths is more specific and tailored for individual applications.

\n\n

There are probably even more options out there besides PATH and App Paths - Windows is full of hidden gems like this 😉.

\n\n

Fun fact: I only discovered App Paths while debugging a problem. We use Process.Start(OUTLOOK) to start Microsofts Outlook Client and I was wondering why this even works.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/01/17/windows-path-and-app-paths/","RawContent":null,"Thumbnail":null},{"Title":".NET ('.NET Core') and Proxy Settings","PublishedOn":"2024-01-12T22:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If your .NET (“.NET Core”) program is running on a system that specifies strict proxy settings, you must either handle these settings in your application itself or use these environment variables.

\n\n

Since I had this problem from time to time and the procedure was not 100% clear to me, I am now recording it here on the blog.

\n\n

“DefaultProxy”

\n\n

If you don’t specify any proxy, then the DefaultProxy is used and depending on your operation system the following will be used:

\n\n

(Copied from here)

\n\n
\n

For Windows: Reads proxy configuration from environment variables or, if those are not defined, from the user’s proxy settings.

\n\n

For macOS: Reads proxy configuration from environment variables or, if those are not defined, from the system’s proxy settings.

\n\n

For Linux: Reads proxy configuration from environment variables or, in case those are not defined, this property initializes a non-configured instance that bypasses all addresses.\nThe environment variables used for DefaultProxy initialization on Windows and Unix-based platforms are:

\n\n

HTTP_PROXY: the proxy server used on HTTP requests.\nHTTPS_PROXY: the proxy server used on HTTPS requests.\nALL_PROXY: the proxy server used on HTTP and/or HTTPS requests in case HTTP_PROXY and/or HTTPS_PROXY are not defined.\nNO_PROXY: a comma-separated list of hostnames that should be excluded from proxying. Asterisks are not supported for wildcards; use a leading dot in case you want to match a subdomain. Examples: > NO_PROXY=.example.com (with leading dot) will match www.example.com, but will not match example.com. NO_PROXY=example.com (without leading dot) will not match www.example.com. This behavior might be > revisited in the future to match other ecosystems better.

\n
\n\n

Scenario: Web-App that needs external & “internal” Web-APIs

\n\n

We often had the following problem: \nOur web application needs to contact external services. This means, that we must use the proxy.\nAt the same time, our web application also wants to communicate with other web APIs on the same machine, but the proxy does not allow this (the proxy can’t return the request to the same machine - not sure why).

\n\n

It should be noted that the “IIS account” or “Network Service” did NOT have a proxy setting itself, i.e. the “User Proxy Settings” were always empty.

\n\n

Solution:

\n\n

We used the following proxy settings and it worked:

\n\n
ALL_PROXY = proxyserver.corp.acme.com\nNO_Proxy = internalserver.corp.acme.com\n
\n\n

Our web application and our internal web api were running on “internalserver.corp.acme.com”. Each request to external services were routed through the proxy and each “internal” request didn’t touch the proxy.

\n\n

IE-Proxy Settings:

\n\n

This solution should work fine on “Server-Environments”. If you have a desktop application, then the “Default Proxy” handling should do the trick. In some special cases the “IE proxy setting” handling might be needed. If you want to learn more about this, read this blogpost: How to use IE proxy settings with HttpClient.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2024/01/12/dotnetcore-and-proxy-settings/","RawContent":null,"Thumbnail":null},{"Title":"Limit Active Directory property access","PublishedOn":"2023-09-20T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Be aware: I’m not a full time administrator and this post might sound stupid to you.

\n\n

The Problem

\n\n

We access certain Active Directory properties with our application, and on one customer domain, we couldn’t retrieve any data via our Active Directory component.

\n\n

Solution

\n\n

After some debugging and doubts about our functionality, the customer admin and I found the reason:\nOur code was running under a Windows account that was very limited and couldn’t read those properties.

\n\n

If you have similar problems, you might want to look into the AD User & Group management.

\n\n

First step: You need to active the advanced features:

\n\n

\"x\"

\n\n

Now navigate to your “user OU” or the target users and check the security tab. The goal is to grant your service account the permission to read the needed property. To do that, go to the advanced view, and add a new permission or change an existing one:

\n\n

\"x\"

\n\n

Here you should be able to see a huge dialog with all available properties and grant the read permission for the target property for your service account.

\n\n

\"x\"

\n\n

Solution via CMD

\n\n

The UI is indeed quite painful to use. If you know what you are doing you can use dsacls.exe.

\n\n

To grant the read permission for tokenGroups for a certain service account you can use the tool like this:

\n\n
dsacls \"OU=Users,DC=company,DC=local\" /I:S /G \"service_account\":rp;tokenGroups;user\n
\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/09/20/limit-active-directory-property-access/","RawContent":null,"Thumbnail":null},{"Title":"Zip deployment failed on Azure","PublishedOn":"2023-09-05T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The Problem

\n\n

We are using Azure App Service for our application (which runs great BTW) and deploy it automatically via ZipDeploy. \nThis basic setup was running smoth, but we noticed that at some point the deployment failed with these error messages:

\n\n
2023-08-24T20:48:56.1057054Z Deployment endpoint responded with status code 202\n2023-08-24T20:49:15.6984407Z Configuring default logging for the app, if not already enabled\n2023-08-24T20:49:18.8106651Z Zip deployment failed. {'id': 'temp-b574d768', 'status': 3, 'status_text': '', 'author_email': 'N/A', 'author': 'N/A', 'deployer': 'ZipDeploy', 'message': 'Deploying from pushed zip file', 'progress': '', 'received_time': '2023-08-24T20:48:55.8916655Z', 'start_time': '2023-08-24T20:48:55.8916655Z', 'end_time': '2023-08-24T20:49:15.3291017Z', 'last_success_end_time': None, 'complete': True, 'active': False, 'is_temp': True, 'is_readonly': False, 'url': 'https://[...].scm.azurewebsites.net/api/deployments/latest', 'log_url': 'https://[...].scm.azurewebsites.net/api/deployments/latest/log', 'site_name': '[...]', 'provisioningState': 'Failed'}. Please run the command az webapp log deployment show\n2023-08-24T20:49:18.8114319Z                            -n [...] -g production\n
\n\n

or this one (depending on how we invoked the deployment script):

\n\n
Getting scm site credentials for zip deployment\nStarting zip deployment. This operation can take a while to complete ...\nDeployment endpoint responded with status code 500\nAn error occured during deployment. Status Code: 500, Details: {\"Message\":\"An error has occurred.\",\"ExceptionMessage\":\"There is not enough space on the disk.\\r\\n\",\"ExceptionType\":\"System.IO.IOException\",\"StackTrace\":\" \n
\n\n

“There is not enough space on the disk”?

\n\n

The message There is not enough space on the disk was a good hint, but according to the File system storage everything should be fine with only 8% used.

\n\n

Be aware - this is important: We have multiple apps on the same App Service plan!

\n\n

\"x\"

\n\n

Kudu to the rescure

\n\n

Next step was to check the behind the scene environment via the “Advanced Tools” Kudu and there it is:

\n\n

\"x\"

\n\n

There are two different storages attached to the app service:

\n\n\n\n

Who is using this space?

\n\n

c:\\local stores “mostly” temporarily items, e.g.:

\n\n
Directory of C:\\local\n\n08/31/2023  06:40 AM    <DIR>          .\n08/31/2023  06:40 AM    <DIR>          ..\n07/13/2023  04:29 PM    <DIR>          AppData\n07/13/2023  04:29 PM    <DIR>          ASP Compiled Templates\n08/31/2023  06:40 AM    <DIR>          Config\n07/13/2023  04:29 PM    <DIR>          DomainValidationTokens\n07/13/2023  04:29 PM    <DIR>          DynamicCache\n07/13/2023  04:29 PM    <DIR>          FrameworkJit\n07/13/2023  04:29 PM    <DIR>          IIS Temporary Compressed Files\n07/13/2023  04:29 PM    <DIR>          LocalAppData\n07/13/2023  04:29 PM    <DIR>          ProgramData\n09/05/2023  08:36 PM    <DIR>          Temp\n08/31/2023  06:40 AM    <DIR>          Temporary ASP.NET Files\n07/18/2023  04:06 AM    <DIR>          UserProfile\n08/19/2023  06:34 AM    <SYMLINKD>     VirtualDirectory0 [\\\\...\\]\n               0 File(s)              0 bytes\n              15 Dir(s)  13,334,384,640 bytes free\n
\n\n

The “biggest” item here was in our case under c:\\local\\Temp\\zipdeploy:

\n\n
 Directory of C:\\local\\Temp\\zipdeploy\n\n08/29/2023  04:52 AM    <DIR>          .\n08/29/2023  04:52 AM    <DIR>          ..\n08/29/2023  04:52 AM    <DIR>          extracted\n08/29/2023  04:52 AM       774,591,927 jiire5i5.zip\n
\n\n

This folder stores our ZipDeploy package, which is quite large with ~800MB. The folder also contains the extracted files - remember: We only have 21GB on this storage, but even if this zip file and the extracted files are ~3GB, there is still plenty of room, right?

\n\n

Shared resources

\n\n

Well… it turns out, that each App Service on a App Service plan is using this storage and if you have multiple App Services on the same plan, than those 21GB might melt away.

\n\n

The “bad” part is, that the space is shared, but each App Services has it’s own c:\\local folder (which makes sense). To free up memory we had to clean up this folder on each App Service like that:

\n\n
rmdir c:\\local\\Temp\\zipdeploy /s /q\n
\n\n

TL;DR

\n\n

If you have problems with ZipDeploy and the error message tells you, that there is not enough space, check out the c:\\local space (and of course c:\\home as well) and delete unused files. Sometimes a reboot might help as well (to clean up temp-files), but AFAIK those ZipDeploy files will survive that.

\n\n","Href":"https://blog.codeinside.eu/2023/09/05/zip-deployment-failed-on-azure-and-how-to-fix-it/","RawContent":null,"Thumbnail":null},{"Title":"First steps with Azure OpenAI and .NET","PublishedOn":"2023-03-23T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The AI world is rising very fast these days: ChatGPT is such an awesome (and scary good?) service and Microsoft joined the ship with some partner announcements and investments. The result is of these actions is, that OpenAI is now a “first class citizen” on Azure.

\n\n

So - for the average Microsoft/.NET developer this opens up a wonderful toolbox and the first steps are really easy.

\n\n

Be aware: You need to “apply” to access the OpenAI service, but it took less then 24 hours for us to gain access to the service. I guess this is just a temporary thing.

\n\n

Disclaimer: I’m not an AI/ML engineer and I only have a very “glimpse” knowledge about the technology behind GPT3, ChatGPT and ML in general. If in doubt, I always ask my buddy Oliver Guhr, because he is much smarter in this stuff. Follow him on Twitter!

\n\n

1. Step: Go to Azure OpenAI Service

\n\n

Search for “OpenAI” and you will see the “Azure OpenAI Service” entry:

\n\n

\"x\"

\n\n

2. Step: Create a Azure OpenAI Service instance

\n\n

Create a new Azure OpenAI Service instance:

\n\n

\"x\"

\n\n

On the next page you will need to enter the subscription, resource group, region and a name (typical Azure stuff):

\n\n

\"x\"

\n\n

Be aware: If your subscription is not enabled for OpenAI, you need to apply here first.

\n\n

3. Step: Overview and create a model

\n\n

After the service is created you should see something like this:

\n\n

\"x\"

\n\n

Now go to “Model deployments” and create a model - I choosed “text-davinci-003”, because I think this is GPT3.5 (which was the initial ChatGPT release, GPT4 is currently in preview for Azure and you need to apply again.

\n\n

\"x\"

\n\n

My guess is, that you could train/deploy other, specialized models here, because this model is quite complex and you might want to tailor the model for your scenario to get faster/cheaper results… but I honestly don’t know how to do it (currently), so we just leave the default.

\n\n

4. Step: Get the endpoint and the key

\n\n

In this step we just need to copy the key and the endpoint, which can be found under “Keys and Endpoint”, simple - right?

\n\n

\"x\"

\n\n

5. Step: Hello World to our Azure OpenAI instance

\n\n

Create a .NET application and add the Azure.AI.OpenAI NuGet package (currently in preview!).

\n\n
dotnet add package Azure.AI.OpenAI --version 1.0.0-beta.5\n
\n\n

Use this code:

\n\n
using Azure.AI.OpenAI;\nusing Azure;\n\nConsole.WriteLine(\"Hello, World!\");\n\nOpenAIClient client = new OpenAIClient(\n        new Uri(\"YOUR-ENDPOINT\"),\n        new AzureKeyCredential(\"YOUR-KEY\"));\n\nstring deploymentName = \"text-davinci-003\";\nstring prompt = \"Tell us something about .NET development.\";\nConsole.Write($\"Input: {prompt}\");\n\nResponse<Completions> completionsResponse = client.GetCompletions(deploymentName, prompt);\nstring completion = completionsResponse.Value.Choices[0].Text;\n\nConsole.WriteLine(completion);\n\nConsole.ReadLine();\n\n
\n\n

Result:

\n\n
Hello, World!\nInput: Tell us something about .NET development.\n\n.NET development is a mature, feature-rich platform that enables developers to create sophisticated web applications, services, and applications for desktop, mobile, and embedded systems. Its features include full-stack programming, object-oriented data structures, security, scalability, speed, and an open source framework for distributed applications. A great advantage of .NET development is its capability to develop applications for both Windows and Linux (using .NET Core). .NET development is also compatible with other languages such as\n
\n\n

As you can see… the result is cut off, not sure why, but this is just a simple demonstration.

\n\n

Summary

\n\n

With these basic steps you can access the OpenAI development world. Azure makes it easy to integrate in your existing Azure/Microsoft “stack”. Be aware, that you could also use the same SDK and use the endpoint from OpenAI. Because of billing reasons it is easier for us to use the Azure hosted instances.

\n\n

Hope this helps!

\n\n

Video on my YouTube Channel

\n\n

If you understand German and want to see it in action, check out my video on my Channel:

\n\n\n\n","Href":"https://blog.codeinside.eu/2023/03/23/first-steps-with-azure-openai-and-dotnet/","RawContent":null,"Thumbnail":null},{"Title":"How to fix: 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine","PublishedOn":"2023-03-18T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In our product we can interact with different datasource and one of these datasources was a Microsoft Access DB connected via OLEDB. This is really, really old, but still works, but on one customer machine we had this issue:

\n\n
'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine\n
\n\n

Solution

\n\n

If you face this issue, you need to install the provider from here.

\n\n

Be aware: If you have a different error, you might need to install the newer provider - this is labled as “2010 Redistributable”, but still works with all those fancy Office 365 apps out there.

\n\n

Important: You need to install the provider in the correct bit version, e.g. if you run under x64, install the x64.msi.

\n\n

The solution comes from this Stackoverflow question.

\n\n

Helper

\n\n

The best tip from Stackoverflow was these powershell commands to check, if the provider is there or not:

\n\n
(New-Object system.data.oledb.oledbenumerator).GetElements() | select SOURCES_NAME, SOURCES_DESCRIPTION \n\nGet-OdbcDriver | select Name,Platform\n
\n\n

This will return something like this:

\n\n
PS C:\\Users\\muehsig> (New-Object system.data.oledb.oledbenumerator).GetElements() | select SOURCES_NAME, SOURCES_DESCRIPTION\n\nSOURCES_NAME               SOURCES_DESCRIPTION\n------------               -------------------\nSQLOLEDB                   Microsoft OLE DB Provider for SQL Server\nMSDataShape                MSDataShape\nMicrosoft.ACE.OLEDB.12.0   Microsoft Office 12.0 Access Database Engine OLE DB Provider\nMicrosoft.ACE.OLEDB.16.0   Microsoft Office 16.0 Access Database Engine OLE DB Provider\nADsDSOObject               OLE DB Provider for Microsoft Directory Services\nWindows Search Data Source Microsoft OLE DB Provider for Search\nMSDASQL                    Microsoft OLE DB Provider for ODBC Drivers\nMSDASQL Enumerator         Microsoft OLE DB Enumerator for ODBC Drivers\nSQLOLEDB Enumerator        Microsoft OLE DB Enumerator for SQL Server\nMSDAOSP                    Microsoft OLE DB Simple Provider\n\n\nPS C:\\Users\\muehsig> Get-OdbcDriver | select Name,Platform\n\nName                                                   Platform\n----                                                   --------\nDriver da Microsoft para arquivos texto (*.txt; *.csv) 32-bit\nDriver do Microsoft Access (*.mdb)                     32-bit\nDriver do Microsoft dBase (*.dbf)                      32-bit\nDriver do Microsoft Excel(*.xls)                       32-bit\nDriver do Microsoft Paradox (*.db )                    32-bit\nMicrosoft Access Driver (*.mdb)                        32-bit\nMicrosoft Access-Treiber (*.mdb)                       32-bit\nMicrosoft dBase Driver (*.dbf)                         32-bit\nMicrosoft dBase-Treiber (*.dbf)                        32-bit\nMicrosoft Excel Driver (*.xls)                         32-bit\nMicrosoft Excel-Treiber (*.xls)                        32-bit\nMicrosoft ODBC for Oracle                              32-bit\nMicrosoft Paradox Driver (*.db )                       32-bit\nMicrosoft Paradox-Treiber (*.db )                      32-bit\nMicrosoft Text Driver (*.txt; *.csv)                   32-bit\nMicrosoft Text-Treiber (*.txt; *.csv)                  32-bit\nSQL Server                                             32-bit\nODBC Driver 17 for SQL Server                          32-bit\nSQL Server                                             64-bit\nODBC Driver 17 for SQL Server                          64-bit\nMicrosoft Access Driver (*.mdb, *.accdb)               64-bit\nMicrosoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb) 64-bit\nMicrosoft Access Text Driver (*.txt, *.csv)            64-bit\n
\n\n

Hope this helps! (And I hope you don’t need to deal with these ancient technologies for too long 😅)

\n","Href":"https://blog.codeinside.eu/2023/03/18/microsoft-ace-oledb-12-0-provider-is-not-registered/","RawContent":null,"Thumbnail":null},{"Title":"Resource type is not supported in this subscription","PublishedOn":"2023-03-11T23:55:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

I was playing around with some Visual Studio Tooling and noticed this error during the creation of a “Azure Container Apps”-app:

\n\n

Resource type is not supported in this subscription

\n\n

\"x\"

\n\n

Solution

\n\n

The solution is quite strange at first, but in the super configurable world of Azure it makes sense: You need to activate the Resource provider for this feature on your subscription. For Azure Container Apps you need the Microsoft.ContainerRegistry-resource provider registered:

\n\n

\"x\"

\n\n

It seems, that you can create such resources via the Portal, but if you go via the API (which Visual Studio seems to do) the provider needs to be registered at first.

\n\n

Some resource providers are “enabled by default”, other providers needs to be turned on manually. Check out this list for a list of all resource providers and the related Azure service.

\n\n

Be careful: I guess you should only enable the resource providers that you really need, otherwise your attack surface will get larger.

\n\n

To be honest: This was completly new for me - I do Azure since ages and never had to deal with resource providers. Always learning ;)

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/03/11/resource-type-is-not-supported-in-this-subscription/","RawContent":null,"Thumbnail":null},{"Title":"Azure DevOps Server 2022 Update","PublishedOn":"2023-02-15T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Azure DevOps Server 2022 - OnPrem?

\n\n

Yes I know - you can get everything from the cloud nowadays, but we are still using our OnPrem hardware and were running the “old” Azure DevOps Server 2020. \nThe _Azure DevOps Server 2022 was released last december, so an update was due.

\n\n

Requirements

\n\n

If you are running am Azure DevOps Server 2020 the requirements for the new 2022 release are “more or less” the same except the following important parts:

\n\n\n\n

Make sure you have a backup

\n\n

The last requirement was a suprise for me, because I thought the update should run smoothly, but the installer removed the previous version and I couldn’t update, because our SQL Server was still on SQL Server 2016. Fortunately we had a VM backup and could rollback to the previous version.

\n\n

Step for Step

\n\n

The update process itself was straightforward: Download the installer and run it.

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

The screenshots are from two different sessions. If you look carefully on the clock you might see that the date is different, that is because of the SQL Server 2016 problem.

\n\n

As you can see - everything worked as expected, but after we updated the server the search, which is powered by ElasticSearch was not working. The “ElasticSearch”-Windows-Service just crashed on startup and I’m not a Java guy, so… we fixed it by removing the search feature and reinstall it. \nWe tried to clean the cache, but it was still not working. After the reinstall of this feature the issue went away.

\n\n

Features

\n\n

Azure Server 2022 is just a minor update (at least from a typical user perspective). The biggest new feature might be “Delivery Plans”, which are nice, but for small teams not a huge benefit. Check out the release notes.

\n\n

A nice - nerdy - enhancement, and not mentioned in the release notes: “mermaid.js” is now supported in the Azure DevOps Wiki, yay!

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/02/15/azure-devops-server-2022-update/","RawContent":null,"Thumbnail":null},{"Title":"Use ASP.NET Core and React with Vite.js","PublishedOn":"2023-02-11T01:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The CRA Problem

\n\n

In my previous post I showed a simple setup with ASP.NET Core & React. The React part was created with the “CRA”-Tooling, which is kind of problematic. The “new” state of the art React tooling seems to be vite.js - so let’s take a look how to use this.

\n\n

\"x\"

\n\n

Step for Step

\n\n

Step 1: Create a “normal” ASP.NET Core project

\n\n

(I like the ASP.NET Core MVC template, but feel free to use something else - same as in the other blogpost)

\n\n

\"x\"

\n\n

Step 2: Install vite.js and init the template

\n\n

Now move to the root directory of your project with a shell and execute this:

\n\n
npm create vite@latest clientapp -- --template react-ts\n
\n\n

This will install the latest & greatest vitejs based react app in a folder called clientapp with the react-ts template (React with Typescript). Vite itself isn’t focused on React and supports many different frontend frameworks.

\n\n

\"x\"

\n\n

Step 3: Enable HTTPS in your vite.js

\n\n

Just like in the “CRA”-setup we need to make sure, that the environment is served under HTTPS. In the “CRA” world we needed to different files from the original ASP.NET Core & React template, but with vite.js there is a much simpler option available.

\n\n

Execute the following command in the clientapp directory:

\n\n
npm install --save-dev vite-plugin-mkcert\n
\n\n

Then in your vite.config.ts use this config:

\n\n
import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport mkcert from 'vite-plugin-mkcert'\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n    base: '/app',\n    server: {\n        https: true,\n        port: 6363\n    },\n    plugins: [react(), mkcert()],\n})\n
\n\n

Be aware: The base: '/app' will be used as a sub-path.

\n\n

The important part for the HTTPS setting is that we use the mkcert() plugin and configure the server part with a port and set https to true.

\n\n

Step 4: Add the Microsoft.AspNetCore.SpaServices.Extensions NuGet package

\n\n

Same as in the other blogpost, we need to add the Microsoft.AspNetCore.SpaServices.Extensions NuGet package to glue the ASP.NET Core development and React world together. If you use .NET 7, then use the version 7.x.x, if you use .NET 6, use the version 6.x.x - etc.

\n\n

\"x\"

\n\n

Step 5: Enhance your Program.cs

\n\n

Back to the Program.cs - this is more or less the same as with the “CRA” setup:

\n\n

Add the SpaStaticFiles to the services collection like this in your Program.cs - be aware, that vite.js builds everything in a folder called dist:

\n\n
var builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\nbuilder.Services.AddControllersWithViews();\n\n// ↓ Add the following lines: ↓\nbuilder.Services.AddSpaStaticFiles(configuration => {\n    configuration.RootPath = \"clientapp/dist\";\n});\n// ↑ these lines ↑\n\nvar app = builder.Build();\n
\n\n

Now we need to use the SpaServices like this:

\n\n
app.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}/{action=Index}/{id?}\");\n\n// ↓ Add the following lines: ↓\nvar spaPath = \"/app\";\nif (app.Environment.IsDevelopment())\n{\n    app.MapWhen(y => y.Request.Path.StartsWithSegments(spaPath), client =>\n    {\n        client.UseSpa(spa =>\n        {\n            spa.UseProxyToSpaDevelopmentServer(\"https://localhost:6363\");\n        });\n    });\n}\nelse\n{\n    app.Map(new PathString(spaPath), client =>\n    {\n        client.UseSpaStaticFiles();\n        client.UseSpa(spa => {\n            spa.Options.SourcePath = \"clientapp\";\n\n            // adds no-store header to index page to prevent deployment issues (prevent linking to old .js files)\n            // .js and other static resources are still cached by the browser\n            spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions\n            {\n                OnPrepareResponse = ctx =>\n                {\n                    ResponseHeaders headers = ctx.Context.Response.GetTypedHeaders();\n                    headers.CacheControl = new CacheControlHeaderValue\n                    {\n                        NoCache = true,\n                        NoStore = true,\n                        MustRevalidate = true\n                    };\n                }\n            };\n        });\n    });\n}\n// ↑ these lines ↑\n\napp.Run();\n
\n\n

Just like in the original blogpost. In the development mode we use the UseProxyToSpaDevelopmentServer-method to proxy all requests to the vite.js dev server. In the real world, we will use the files from the dist folder.

\n\n

Step 6: Invoke npm run build during publish

\n\n

The last step is to complete the setup. We want to build the ASP.NET Core app and the React app, when we use dotnet publish:

\n\n

Add this to your .csproj-file and it should work:

\n\n
\t<PropertyGroup>\n\t\t<SpaRoot>clientapp\\</SpaRoot>\n\t</PropertyGroup>\n\n\t<Target Name=\"PublishRunWebpack\" AfterTargets=\"ComputeFilesToPublish\">\n\t\t<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm install\" />\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm run build\" />\n\n\t\t<!-- Include the newly-built files in the publish output -->\n\t\t<ItemGroup>\n\t\t\t<DistFiles Include=\"$(SpaRoot)dist\\**\" />  <!-- Changed to dist! -->\n\t\t\t<ResolvedFileToPublish Include=\"@(DistFiles->'%(FullPath)')\" Exclude=\"@(ResolvedFileToPublish)\">\n\t\t\t\t<RelativePath>%(DistFiles.Identity)</RelativePath> <!-- Changed! -->\n\t\t\t\t<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n\t\t\t\t<ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n\t\t\t</ResolvedFileToPublish>\n\t\t</ItemGroup>\n\t</Target>\n
\n\n

Result

\n\n

You should now be able to use Visual Studio Code (or something like this) and start the frontend project with dev. If you open a browser and go to https://127.0.0.1:6363/app you should see something like this:

\n\n

\"x\"

\n\n

Now start the ASP.NET Core app and go to /app and it should look like this:

\n\n

\"x\"

\n\n

Ok - this looks broken, right? Well - this is a more or less a “known” problem, but can be easily avoided. If we import the logo from the assets it works as expected and shouldn’t be a general problem:

\n\n

\"x\"

\n\n

Code

\n\n

The sample code can be found here.

\n\n

Video

\n\n

I made a video about this topic (in German, sorry :-/) as well - feel free to subscribe ;)

\n\n\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/02/11/aspnet-core-react-with-vitejs/","RawContent":null,"Thumbnail":null},{"Title":"Use ASP.NET Core & React togehter","PublishedOn":"2023-01-25T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The ASP.NET Core React template

\n\n

\"x\"

\n\n

Visual Studio (at least VS 2019 and the newer 2022) ships with a ASP.NET Core React template, which is “ok-ish”, but has some really bad problems:

\n\n

The React part of this template is scaffolded via “CRA” (which seems to be problematic as well, but is not the point of this post) and uses JavaScript instead of TypeScript.\nAnother huge pain point (from my perspective) is that the template uses some special configurations to just host the react part for users - if you want to mix in some “MVC”/”Razor” stuff, you need to change some of this “magic”.

\n\n

The good parts:

\n\n

Both worlds can live together: During development time the ASP.NET Core stuff is hosted via Kestrel and the React part is hosted under the WebPack Development server. The lovely hot reload is working as expected and is really powerful.\nIf you are doing a release build, the project will take care of the npm-magic.

\n\n

But because of the “bad problems” outweight the benefits, we try to integrate a typical react app in a “normal” ASP.NET Core app.

\n\n

Step for Step

\n\n

Step 1: Create a “normal” ASP.NET Core project

\n\n

(I like the ASP.NET Core MVC template, but feel free to use something else)

\n\n

\"x\"

\n\n

Step 2: Create a react app inside the ASP.NET Core project

\n\n

(For this blogpost I use the “Create React App”-approach, but you can use whatever you like)

\n\n

Execute this in your ASP.NET Core template (node & npm must be installed!):

\n\n
npx create-react-app clientapp --template typescript\n
\n\n

Step 3: Copy some stuff from the React template

\n\n

The react template ships with some scripts and settings that we want to preserve:

\n\n

\"x\"

\n\n

The aspnetcore-https.js and aspnetcore-react.js file is needed to setup the ASP.NET Core SSL dev certificate for the WebPack Dev Server. \nYou should also copy the .env & .env.development file in the root of your clientapp-folder!

\n\n

The .env file only has this setting:

\n\n
BROWSER=none\n
\n\n

A more important setting is in the .env.development file (change the port to something different!):

\n\n
PORT=3333\nHTTPS=true\n
\n\n

The port number 3333 and the https=true will be important later, otherwise our setup will not work.

\n\n

Also, add this line to the .env-file (in theory you can use any name - for this sample we keep it spaApp):

\n\n
PUBLIC_URL=/spaApp\n
\n\n

Step 4: Add the prestart to the package.json

\n\n

In your project open the package.json and add the prestart-line like this:

\n\n
  \"scripts\": {\n    \"prestart\": \"node aspnetcore-https && node aspnetcore-react\",\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\"\n  },\n
\n\n

Step 5: Add the Microsoft.AspNetCore.SpaServices.Extensions NuGet package

\n\n

\"x\"

\n\n

We need the Microsoft.AspNetCore.SpaServices.Extensions NuGet-package. If you use .NET 7, then use the version 7.x.x, if you use .NET 6, use the version 6.x.x - etc.

\n\n

Step 6: Enhance your Program.cs

\n\n

Add the SpaStaticFiles to the services collection like this in your Program.cs:

\n\n
var builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\nbuilder.Services.AddControllersWithViews();\n\n// ↓ Add the following lines: ↓\nbuilder.Services.AddSpaStaticFiles(configuration => {\n    configuration.RootPath = \"clientapp/build\";\n});\n// ↑ these lines ↑\n\nvar app = builder.Build();\n
\n\n

Now we need to use the SpaServices like this:

\n\n
app.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}/{action=Index}/{id?}\");\n\n// ↓ Add the following lines: ↓\nvar spaPath = \"/spaApp\";\nif (app.Environment.IsDevelopment())\n{\n    app.MapWhen(y => y.Request.Path.StartsWithSegments(spaPath), client =>\n    {\n        client.UseSpa(spa =>\n        {\n            spa.UseProxyToSpaDevelopmentServer(\"https://localhost:3333\");\n        });\n    });\n}\nelse\n{\n    app.Map(new PathString(spaPath), client =>\n    {\n        client.UseSpaStaticFiles();\n        client.UseSpa(spa => {\n            spa.Options.SourcePath = \"clientapp\";\n\n            // adds no-store header to index page to prevent deployment issues (prevent linking to old .js files)\n            // .js and other static resources are still cached by the browser\n            spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions\n            {\n                OnPrepareResponse = ctx =>\n                {\n                    ResponseHeaders headers = ctx.Context.Response.GetTypedHeaders();\n                    headers.CacheControl = new CacheControlHeaderValue\n                    {\n                        NoCache = true,\n                        NoStore = true,\n                        MustRevalidate = true\n                    };\n                }\n            };\n        });\n    });\n}\n// ↑ these lines ↑\n\napp.Run();\n
\n\n

As you can see, we run in two different modes. \nIn our development world we just use the UseProxyToSpaDevelopmentServer-method to proxy all requests that points to spaApp to the React WebPack DevServer (or something else). The huge benefit is, that you can use the React ecosystem with all its tools. Normally we use Visual Studio Code to run our react frontend and use the ASP.NET Core app as the “Backend for frontend”.\nIn production we use the build artefacts of the react build and make sure, that it’s not cached. To make the deployment easier, we need to invoke npm run build when we publish this ASP.NET Core app.

\n\n

Step 7: Invoke npm run build during publish

\n\n

Add this to your .csproj-file and it should work:

\n\n
\t<PropertyGroup>\n\t\t<SpaRoot>clientapp\\</SpaRoot>\n\t</PropertyGroup>\n\n\t<Target Name=\"PublishRunWebpack\" AfterTargets=\"ComputeFilesToPublish\">\n\t\t<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm install\" />\n\t\t<Exec WorkingDirectory=\"$(SpaRoot)\" Command=\"npm run build\" />\n\n\t\t<!-- Include the newly-built files in the publish output -->\n\t\t<ItemGroup>\n\t\t\t<DistFiles Include=\"$(SpaRoot)build\\**\" />\n\t\t\t<ResolvedFileToPublish Include=\"@(DistFiles->'%(FullPath)')\" Exclude=\"@(ResolvedFileToPublish)\">\n\t\t\t\t<RelativePath>%(DistFiles.Identity)</RelativePath> <!-- Changed! -->\n\t\t\t\t<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n\t\t\t\t<ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n\t\t\t</ResolvedFileToPublish>\n\t\t</ItemGroup>\n\t</Target>\n
\n\n

Be aware that these instruction are copied from the original ASP.NET Core React template and are slightly modified, otherwise the path wouldn’t match.

\n\n

Result

\n\n

With this setup you can add any spa app that you would like to add to your “normal” ASP.NET Core project.

\n\n

If everything works as expected you should be able to start the React app in Visual Studio Code like this:

\n\n

\"x\"

\n\n

Be aware of the https://localhost:3333/spaApp. The port and the name is important for our sample!

\n\n

Start your hosting ASP.NET Core app in Visual Studio (or in any IDE that you like) and all requests that points to spaApp use the WebPack DevServer in the background:

\n\n

\"x\"

\n\n

With this setup you can mix all client & server side styles as you like - mission succeeded and you can use any client setup (CRA, anything else) as you would like to.

\n\n

Code

\n\n

The code (but with slightly modified values (e.g. another port)) can be found here. \nBe aware, that npm i needs to be run first.

\n\n

Video

\n\n

I uploaded a video on my YouTube channel (in German) about this setup:

\n\n\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/01/25/aspnet-core-and-react/","RawContent":null,"Thumbnail":null},{"Title":"Your URL is flagged as malware/phishing, now what?","PublishedOn":"2023-01-04T22:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Problem

\n\n

On my last day in 2022 - Friday, 23. December, I received a support ticket from one customer, that our software seems to be offline and it looks like that our servers are not responding. I checked our monitoring and the server side of the customer and everything was fine. \nMy first thought: Maybe a misconfiguration on the customer side, but after a remote support session with the customer, I saw that it “should work”, but something in the customer network blocks the requests to our services.\nNext thought: Firewall or proxy stuff. Always nasty, but we are just using port 443, so nothing too special.

\n\n

After a while I received a phone call from the customers firewall team and they discovered the problem: They are using a firewall solution from “Check Point” and our domain was flagged as “phishing”/”malware”. What the… \nThey even created an exception so that Check Point doesn’t block our requests, but the next problem occured: The customers “Windows Defender for Office 365” has the same “flag” for our domain, so they revert everything, because they didn’t want to change their settings too much.

\n\n

\"x\"

\n\n

Be aware, that from our end everything was working “fine” and I could access the customer services and our Windows Defender didn’t had any problems with this domain.

\n\n

Solution

\n\n

Somehow our domain was flagged as malware/phishing and we needed to change this false positive listening. I guess there are tons of services, that “tracks” “bad” websites and maybe all are connected somehow. From this indicent I can only suggest:

\n\n

If you have trouble with Check Point:

\n\n

Go to “URLCAT”, register an account and try to change the category of your domain. After you submit the “change request” you will get an email like this:

\n\n
Thank you for submitting your category change request.\nWe will process your request and notify you by email (to: xxx.xxx@xxx.com ).\nYou can follow the status of your request on this page.\nYour request details\nReference ID: [GUID]\nURL: https://[domain].com\nSuggested Categories: Computers / Internet,Business / Economy\nComment: [Given comment]\n
\n\n

After ~1-2 days the change was done. Not sure if this is automated or not, but it was during Christmas.

\n\n

If you have trouble with Windows Defender:

\n\n

Go to “Report submission” in your Microsoft 365 Defender setting (you will need an account with special permissions, e.g. global admin) and add the URL as “Not junk”.

\n\n

\"x\"

\n\n

I’m not really sure if this helped or not, because we didn’t had any issues with the domain itself and I’m not sure if those “false positive” tickets bubbles up into a “global defender catalog” or if this only affects our own tenant.

\n\n

Result

\n\n

Anyway - after those tickets were “resolved” by Check Point / Microsoft the problem on the customer side disappeared and everyone was happy. This was my first experience with such an “false positive malware report”. I’m not sure how we ended up on such a list and why only one customer was affected.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2023/01/04/checkpoint-and-defender-false-positive-url/","RawContent":null,"Thumbnail":null},{"Title":"SQLLocalDb update","PublishedOn":"2022-12-03T22:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Short Intro

\n\n

SqlLocalDb is a “developer” SQL server, without the “full” SQL Server (Express) installation. If you just develop on your machine and don’t want to run a “full blown” SQL Server, this is the tooling that you might need.

\n\n

From the Microsoft Docs:

\n\n
\n

Microsoft SQL Server Express LocalDB is a feature of SQL Server Express targeted to developers. It is available on SQL Server Express with Advanced Services.

\n\n

LocalDB installation copies a minimal set of files necessary to start the SQL Server Database Engine. Once LocalDB is installed, you can initiate a connection using a special connection string. When connecting, the necessary SQL Server infrastructure is automatically created and started, enabling the application to use the database without complex configuration tasks. Developer Tools can provide developers with a SQL Server Database Engine that lets them write and test Transact-SQL code without having to manage a full server instance of SQL Server.

\n
\n\n

Problem

\n\n

(I’m not really sure, how I ended up on this problem, but I after I solved the problem I did it on my “To Blog”-bucket list)

\n\n

From time to time there is a new SQLLocalDb version, but to upgrade an existing installation is a bit “weird”.

\n\n

Solution

\n\n

If you have installed an older SQLLocalDb version you can manage it via sqllocaldb. If you want to update you must delete the “current” MSSQLLocalDB in the first place.

\n\n

To to this use:

\n\n
sqllocaldb stop MSSQLLocalDB\nsqllocaldb delete MSSQLLocalDB\n
\n\n

Then download the newest version from Microsoft. \nIf you choose “Download Media” you should see something like this:

\n\n

\"x\"

\n\n

Download it, run it and restart your PC, after that you should be able to connect to the SQLLocalDb.

\n\n

We solved this issue with help of this blogpost.

\n\n

Hope this helps! (and I can remove it now from my bucket list \\o/ )

\n","Href":"https://blog.codeinside.eu/2022/12/03/sqllocaldb-update/","RawContent":null,"Thumbnail":null},{"Title":"Azure DevOps & Azure Service Connection","PublishedOn":"2022-10-04T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Today I needed to setup a new release pipeline on our Azure DevOps Server installation to deploy some stuff automatically to Azure. The UI (at least on the Azure DevOps Server 2020 (!)) is not really clear about how to connect those two worlds, and thats why I’m writing this short blogpost.

\n\n

First - under project settings - add a new service connection. Use the Azure Resource Manager-service. Now you should see something like this:

\n\n

\"x\"

\n\n

Be aware: You will need to register app inside your Azure AD and need permissions to setup. If you are not able to follow these instructions, you might need to talk to your Azure subscription owner.

\n\n

Subscription id:

\n\n

Copy here the id of your subscription. This can be found in the subscription details:

\n\n

\"x\"

\n\n

Keep this tab open, because we need it later!

\n\n

Service prinipal id/key & tenant id:

\n\n

Now this wording about “Service principal” is technically correct, but really confusing if your are not familar with Azure AD. A “Service prinipal” is like a “service user”/”app” that you need to register to use it.\nThe easiest route is to create an app via the Bash Azure CLI:

\n\n
az ad sp create-for-rbac --name DevOpsPipeline\n
\n\n

If this command succeeds you should see something like this:

\n\n
{\n  \"appId\": \"[...GUID..]\",\n  \"displayName\": \"DevOpsPipeline\",\n  \"password\": \"[...PASSWORD...]\",\n  \"tenant\": \"[...Tenant GUID...]\"\n}\n
\n\n

This creates an “Serivce principal” with a random password inside your Azure AD. The next step is to give this “Service principal” a role on your subscription, because it has currently no permissions to do anything (e.g. deploy a service etc.).

\n\n

Go to the subscription details page and then to Access control (IAM). There you can add your “DevOpsPipeline”-App as “Contributor” (Be aware that this is a “powerful role”!).

\n\n

After that use the \"appId\": \"[...GUID..]\" from the command as Service Principal Id. \nUse the \"password\": \"[...PASSWORD...]\" as Service principal key and the \"tenant\": \"[...Tenant GUID...]\" for the tenant id.

\n\n

Now you should be able to “Verify” this connection and it should work.

\n\n

Links:\nThis blogpost helped me a lot. Here you can find the official documentation.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/10/04/azure-devops-azure-service-connection/","RawContent":null,"Thumbnail":null},{"Title":"'error MSB8011: Failed to register output.' & UTF8-BOM files","PublishedOn":"2022-08-30T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Be aware: I’m not a C++ developer and this might be an “obvious” problem, but it took me a while to resolve this issue.

\n\n

In our product we have very few C++ projects. We use these projects for very special Microsoft Office COM stuff and because of COM we need to register some components during the build. Everything worked as expected, but we renamed a few files and our build broke with:

\n\n
C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\MSBuild\\Microsoft\\VC\\v170\\Microsoft.CppCommon.targets(2302,5): warning MSB3075: The command \"regsvr32 /s \"C:/BuildAgentV3_1/_work/67/s\\_Artifacts\\_ReleaseParts\\XXX.Client.Addin.x64-Shims\\Common\\XXX.Common.Shim.dll\"\" exited with code 5. Please verify that you have sufficient rights to run this command. [C:\\BuildAgentV3_1\\_work\\67\\s\\XXX.Common.Shim\\XXX.Common.Shim.vcxproj]\nC:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\MSBuild\\Microsoft\\VC\\v170\\Microsoft.CppCommon.targets(2314,5): error MSB8011: Failed to register output. Please try enabling Per-user Redirection or register the component from a command prompt with elevated permissions. [C:\\BuildAgentV3_1\\_work\\67\\s\\XXX.Common.Shim\\XXX.Common.Shim.vcxproj]\n\n(xxx = redacted)\n
\n\n

The crazy part was: Using an older version of our project just worked as expected, but all changes were “fine” from my point of view.

\n\n

After many, many attempts I remembered that our diff tool doesn’t show us everything - so I checked the file encodings: UTF8-BOM

\n\n

Somehow if you have a UTF8-BOM encoded file that your C++ project uses to register COM stuff it will fail. I changed the encoding and to UTF8 and everyting worked as expected.

\n\n

What a day… lessons learned: Be aware of your file encodings.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/08/30/error-msb8011-failed-to-register-output-and-utf8bom/","RawContent":null,"Thumbnail":null},{"Title":"Which .NET Framework Version is installed on my machine?","PublishedOn":"2022-08-29T23:15:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

If you need to know which .NET Framework Version (the “legacy” .NET Framework) is installed on your machine try this handy oneliner:

\n\n
Get-ItemProperty \"HKLM:SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\"\n
\n\n

Result:

\n\n
CBS           : 1\nInstall       : 1\nInstallPath   : C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\\nRelease       : 528372\nServicing     : 0\nTargetVersion : 4.0.0\nVersion       : 4.8.04084\nPSPath        : Microsoft.PowerShell.Core\\Registry::HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework\n                Setup\\NDP\\v4\\Full\nPSParentPath  : Microsoft.PowerShell.Core\\Registry::HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\nPSChildName   : Full\nPSDrive       : HKLM\nPSProvider    : Microsoft.PowerShell.Core\\Registry\n
\n\n

The version should give you more then enough information.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/08/29/which-dotnet-version-is-installed-via-powershell/","RawContent":null,"Thumbnail":null},{"Title":"How to run a Azure App Service WebJob with parameters","PublishedOn":"2022-07-22T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We are using WebJobs in our Azure App Service deployment and they are pretty “easy” for the most part. Just register a WebJobs or deploy your .exe/.bat/.ps1/... under the \\site\\wwwroot\\app_data\\Jobs\\triggered folder and it should execute as described in the settings.job.

\n\n

\"x\"

\n\n

If you put any executable in this WebJob folder, it will be executed as planned.

\n\n

Problem: Parameters

\n\n

If you have a my-job.exe, then this will be invoked from the runtime. But what if you need to invoke it with a parameter like my-job.exe -param \"test\"?

\n\n

Solution: run.cmd

\n\n

The WebJob environment is “greedy” and will search for a run.cmd (or run.exe) and if this is found, it will be executed and it doesn’t matter if you have any other .exe files there.\nStick to the run.cmd and use this to invoke your actual executable like this:

\n\n
echo \"Invoke my-job.exe with parameters - Start\"\n\n..\\MyJob\\my-job.exe -param \"test\"\n\necho \"Invoke my-job.exe with parameters - Done\"\n
\n\n

Be aware, that the path must “match”. We use this run.cmd-approach in combination with the is_in_place-option (see here) and are happy with the results).

\n\n

A more detailed explanation can be found here.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/07/22/how-to-run-a-azure-appservice-webjob-with-parameters/","RawContent":null,"Thumbnail":null},{"Title":"How to use IE proxy settings with HttpClient","PublishedOn":"2022-03-28T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Internet Explorer is - mostly - dead, but some weird settings are still around and “attached” to the old world, at least on Windows 10. \nIf your system administrator uses some advanced proxy settings (e.g. a PAC-file), those will be attached to the users IE setting.

\n\n

If you want to use this with a HttpClient you need to code something like this:

\n\n
    string target = \"https://my-target.local\";\n    var targetUri = new Uri(target);\n    var proxyAddressForThisUri = WebRequest.GetSystemWebProxy().GetProxy(targetUri);\n    if (proxyAddressForThisUri == targetUri)\n    {\n        // no proxy needed in this case\n        _httpClient = new HttpClient();\n    }\n    else\n    {\n        // proxy needed\n        _httpClient = new HttpClient(new HttpClientHandler() { Proxy = new WebProxy(proxyAddressForThisUri) { UseDefaultCredentials = true } });\n    }\n
\n\n

The GetSystemWebProxy() gives access to the system proxy settings from the current user. Then we can query, what proxy is needed for the target. If the result is the same address as the target, then no proxy is needed. Otherwise, we inject a new WebProxy for this address.

\n\n

Hope this helps!

\n\n

Be aware: Creating new HttpClients is (at least in a server environment) not recommended. Try to reuse the same HttpClient instance!

\n\n

Also note: The proxy setting in Windows 11 are now built into the system settings, but the API still works :)

\n\n

\"x\"

\n","Href":"https://blog.codeinside.eu/2022/03/28/how-to-use-ie-proxy-settings-with-httpclient/","RawContent":null,"Thumbnail":null},{"Title":"Redirect to HTTPS with a simple web.config rule","PublishedOn":"2022-01-05T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The scenario is easy: My website is hosted in an IIS and would like to redirect all incomming HTTP traffic to the HTTPS counterpart.

\n\n

This is your solution - a “simple” rule:

\n\n
<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n    <system.webServer>\n        <rewrite>\n            <rules>\n                <rule name=\"Redirect to https\" stopProcessing=\"true\">\n                    <match url=\".*\" />\n                    <conditions logicalGrouping=\"MatchAny\">\n                        <add input=\"{HTTPS}\" pattern=\"off\" />\n                    </conditions>\n                    <action type=\"Redirect\" url=\"https://{HTTP_HOST}{REQUEST_URI}\" redirectType=\"Found\" />\n                </rule>\n            </rules>\n        </rewrite>\n    </system.webServer>\n</configuration>\n
\n\n

We used this in the past to setup a “catch all” web site in an IIS that redirects all incomming HTTP traffic.\nThe actual web applications had only the HTTPS binding in place.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2022/01/05/redirect-to-https-with-a-simple-webconfig-rule/","RawContent":null,"Thumbnail":null},{"Title":"Select random rows","PublishedOn":"2021-12-06T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Let’s say we have a SQL table and want to retrieve 10 rows randomly - how would you do that? Although I have been working with SQL for x years, I have never encountered that problem. The solution however is quite “simple” (at least if you don’t be picky how we define “randomness” and if you try this on millions of rows):

\n\n

ORDER BY NEWID()

\n\n

The most boring way is to use the ORDER BY NEWID() clause:

\n\n
SELECT TOP 10 FROM Products ORDER BY NEWID()\n
\n\n

This works, but if you do that on “large” datasets you might hit performance problems (e.g. more on that here)

\n\n

TABLESAMPE

\n\n

The SQL Server implements the Tablesample clause which was new to me. It seems to perform much bettern then the ORDER BY NEWID() clause, but behaves a bit weird. With this clause you can specify the “sample” from a table. The size of the sample can be specified as PERCENT or ROWS (which are then converted to percent internally).

\n\n

Syntax:

\n\n
SELECT TOP 10 FROM Products TABLESAMPLE (25 Percent)\nSELECT TOP 10 FROM Products TABLESAMPLE (100 ROWS)\n
\n\n

The weird part is that the given number might not match the number of rows of your result. You might got more or less results and if our tablesample is too small you might even got nothing in return. There are some clever ways to work around this (e.g. using the TOP 100 statement with a much larger tablesample clause to get a guaranteed result set), but it feels “strange”.\nIf you hit limitations with the first solution you might want to read more on this blog or in the Microsoft Docs.

\n\n

Stackoverflow

\n\n

Of course there is a great Stackoverflow thread with even wilder solutions.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/12/06/select-random-rows/","RawContent":null,"Thumbnail":null}],"ResultType":"Feed"},"YouTube":{"FeedItems":[{"Title":"Erste Schritte mit dem Azure OpenAI Service","PublishedOn":"2023-03-23T22:30:48+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=VVNHT4gVxDo","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/VVNHT4gVxDo/hqdefault.jpg"},{"Title":"Erster Schritt in die Source Control: Visual Studio Projekte auf GitHub pushen","PublishedOn":"2023-03-17T21:59:57+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=iKQS5nYbC-k","RawContent":null,"Thumbnail":"https://i2.ytimg.com/vi/iKQS5nYbC-k/hqdefault.jpg"},{"Title":"Vite.js für React & TypeScript für ASP.NET Core & Visual Studio Entwickler","PublishedOn":"2023-02-12T00:25:03+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=-2iiXpBcmDY","RawContent":null,"Thumbnail":"https://i2.ytimg.com/vi/-2iiXpBcmDY/hqdefault.jpg"},{"Title":"React.js mit TypeScript in ASP.NET Core mit Visual Studio & Visual Studio Code","PublishedOn":"2023-01-26T23:35:26+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=IgW79wxMO-c","RawContent":null,"Thumbnail":"https://i2.ytimg.com/vi/IgW79wxMO-c/hqdefault.jpg"},{"Title":"React.js mit ASP.NET Core - ein Einstieg mit Visual Studio","PublishedOn":"2022-10-07T23:15:55+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=gIzMtWDs_QM","RawContent":null,"Thumbnail":"https://i4.ytimg.com/vi/gIzMtWDs_QM/hqdefault.jpg"},{"Title":"Einstieg in die Webentwicklung mit .NET 6 & ASP.NET Core","PublishedOn":"2022-04-12T21:13:18+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=WtpzsW5Xwqo","RawContent":null,"Thumbnail":"https://i4.ytimg.com/vi/WtpzsW5Xwqo/hqdefault.jpg"},{"Title":"Das erste .NET 6 Programm","PublishedOn":"2022-01-30T22:21:35+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=fVzo2qJubmA","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/fVzo2qJubmA/hqdefault.jpg"},{"Title":"Azure SQL - ist das echt so teuer? Neee...","PublishedOn":"2022-01-11T21:49:29+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=dNaIOGQj15M","RawContent":null,"Thumbnail":"https://i1.ytimg.com/vi/dNaIOGQj15M/hqdefault.jpg"},{"Title":"Was sind \"Project Templates\" in Visual Studio?","PublishedOn":"2021-12-22T22:36:25+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=_IMabo9yHSA","RawContent":null,"Thumbnail":"https://i4.ytimg.com/vi/_IMabo9yHSA/hqdefault.jpg"},{"Title":".NET Versionen - was bedeutet LTS und Current?","PublishedOn":"2021-12-21T21:06:29+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=2ghTKF0Ey_0","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/2ghTKF0Ey_0/hqdefault.jpg"},{"Title":"Einstieg in die .NET Entwicklung für Anfänger","PublishedOn":"2021-12-20T22:18:35+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=2EcSJDX-8-s","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/2EcSJDX-8-s/hqdefault.jpg"},{"Title":"Erste Schritte mit Unit Tests","PublishedOn":"2008-11-05T00:14:06+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=tjAv1-Qb4rY","RawContent":null,"Thumbnail":"https://i1.ytimg.com/vi/tjAv1-Qb4rY/hqdefault.jpg"},{"Title":"3 Schichten Architektur","PublishedOn":"2008-10-17T22:01:06+00:00","CommentsCount":0,"FacebookCount":0,"Summary":null,"Href":"https://www.youtube.com/watch?v=27yknlB8xeg","RawContent":null,"Thumbnail":"https://i3.ytimg.com/vi/27yknlB8xeg/hqdefault.jpg"}],"ResultType":"Feed"},"O_Blog":{"FeedItems":[{"Title":"How to build a simple hate speech detector with machine learning","PublishedOn":"2019-08-02T13:00:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"

Not everybody on the internet behaves nice and some comments are just rude or offending. If you run a web page that offers a public comment function hate speech can be a real problem. For example in Germany, you are legally required to delete hate speech comments. This can be challenging if you have to check thousands of comments each day. \nSo wouldn’t it be nice, if you can automatically check the user’s comment and give them a little hint to stay nice?\n

\n\n

The simplest thing you could do is to check if the user’s text contains offensive words. However, this approach is limited since you can offend people without using offensive words.

\n\n

This post will show you how to train a machine learning model that can detect if a comment or text is offensive. And to start you need just a few lines of Python code \\o/

\n\n

The Data

\n\n

At first, you need data. In this case, you will need a list of offensive and nonoffensive texts. I wrote this tutorial for a machine learning course in Germany, so I used German texts but you should be able to use other languages too.

\n\n

For a machine learning competition, scientists provided a list of comments labeled as offensive and nonoffensive (Germeval 2018, Subtask 1). This is perfect for us since we just can use this data.

\n\n

The Code

\n\n

To tackle this task I would first establish a baseline and then improve this solution step by step. Luckily they also published the scores of all submission, so we can get a sense of how well we are doing.

\n\n

For our baseline model we are going to use Facebooks fastText. It’s simple to use, works with many languages and does not require any special hardware like a GPU. Oh, and it’s fast :)

\n\n

1. Load the data

\n\n

After you downloaded the training data file germeval2018.training.txt you need to transform this data into a format that fastText can read.\nFastTexts standard format looks like this “label[your label] some text”:

\n\n
__label__offensive some insults\n__label__other have a nice day\n
\n\n

2. Train the Model

\n\n

To train the model you need to install the fastText Python package.

\n\n
$ pip install fasttext\n
\n

To train the model you need just there line of code.

\n
import fasttext\ntraning_parameters = {'epoch': 50, 'lr': 0.05, 'loss': \"ns\", 'thread': 8, 'ws': 5, 'dim': 100}    \nmodel = fasttext.supervised('fasttext.train', 'model', **traning_parameters)\n
\n\n

I packed all the training parameters into a seperate dictionary. To me that looks a bit cleaner but you don’t need to do that.

\n\n

3. Test your Model

\n\n

After we trained the model it is time to test how it performs. FastText provides us a handy test method the evaluate the model’s performance. To compare our model with the other models from the GermEval contest I also added a lambda which calculates the average F1 score. For now, I did not use the official test script from the contests repository. Which you should do if you wanted to participate in such contests.

\n\n
def test(model):\n    f1_score = lambda precision, recall: 2 * ((precision * recall) / (precision + recall))\n    nexamples, recall, precision = model.test('fasttext.test')\n    print (f'recall: {recall}' )\n    print (f'precision: {precision}')\n    print (f'f1 score: {f1_score(precision,recall)}')\n    print (f'number of examples: {nexamples}')\n
\n\n

I don’t know about you, but I am so curious how we score. Annnnnnnd:

\n\n
recall: 0.7018686296715742\nprecision: 0.7018686296715742\nf1 score: 0.7018686296715742\nnumber of examples: 3532\n
\n\n

Looking at the results we can see that the best other model had an average F1 score of 76,77 and our model achieves -without any optimization and preprocessing- an F1 Score of 70.18.

\n\n

This is pretty good since the models for these contests are usually specially optimized for the given data.

\n\n

FastText is a clever piece of software, that uses some neat tricks. If interested in fastText you should take a look the paper and this one. For example, fastText uses character n-grams. This approach is well suited for the German language, which uses a lot of compound words.

\n\n

Next Steps

\n\n

In this very basic tutorial, we trained a model with just a few lines of Python code. There are several things you can do to improve this model. The first step would be to preprocess your data. During preprocessing you could lower case all texts, remove URLs and special characters, correct spelling, etc. After every optimization step, you can test your model and check if your scores went up. Happy hacking :)

\n\n

Some Ideas:

\n\n
    \n
  1. Preprocess the data
  2. \n
  3. Optimize the parameters (number of training epochs, learning rate, embedding dims, word n-grams)
  4. \n
  5. Use pre-trained word vectors from the fastText website
  6. \n
  7. add more data to the training set
  8. \n
  9. Use data augmentation.
  10. \n
\n\n

Here is the full code:

\n\n\n\n

Credit: Photo by Jon Tyson on Unsplash

","Href":"https://www.oliverguhr.eu/nlp/jekyll/2019/08/02/build-a-simple-hate-speech-detector-with-machine-learning.html","RawContent":null,"Thumbnail":null}],"ResultType":"Feed"},"GitHubEventsUser":{"Events":[{"Id":"42018108069","Type":"IssuesEvent","CreatedAt":"2024-09-17T21:16:23","Actor":"robertmuehsig","Repository":"GregorBiswanger/OllamaApiFacade","Organization":null,"RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/GregorBiswanger/OllamaApiFacade/issues/1","RelatedDescription":"Opened issue \"Create an Open AI compatible facade\" (#1) at GregorBiswanger/OllamaApiFacade","RelatedBody":"Ollama itself is compatible with the [Open AI spec](https://ollama.com/blog/openai-compatibility) and it would be cool to \"embed\" or host an Open AI compatible facade with .NET.\r\n\r\nReason/Goal:\r\n\r\nI want to use the existing Open AI NuGet package and work against a local hosted LLM. There are some ideas in the [LLamaSharp](https://github.com/SciSharp/LLamaSharp/issues/269) repo, but it seems to be tricky. \r\n\r\nYour project looks promising ;)"},{"Id":"41628817944","Type":"IssuesEvent","CreatedAt":"2024-09-04T18:05:32","Actor":"robertmuehsig","Repository":"sangyuxiaowu/LLamaWorker","Organization":null,"RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/sangyuxiaowu/LLamaWorker/issues/23","RelatedDescription":"Opened issue \"Configuration Guide - running in an error while streaming\" (#23) at sangyuxiaowu/LLamaWorker","RelatedBody":"Hi,\r\nI was looking for a combination of LlamaSharp and the OpenAI REST API and this project looks promising.\r\n\r\nMy \"basic need\" would be to simulate the OpenAI REST API like LM Studio did. All I want is to load the Phi3 model and be done.\r\n![image](https://github.com/user-attachments/assets/80ea0488-199d-4bf5-9ee2-f9c9ef499235)\r\n\r\nNow my question: I just changed the paths and deleted the other models in the appsettings, but I wonder: Which properties are \"important\" and what does each setting do?\r\n\r\nMy setting now looks like this - is this \"ok\" or would this break something?\r\n\r\n```\r\n...\r\n \"GlobalSettings\": {\r\n \"CurrentModelIndex\": 0,\r\n // 自动释放时间,分钟。0 表示不自动释放\r\n \"AutoReleaseTime\": 30\r\n },\r\n // LLM 服务配置\r\n \"LLmModelSettings\": [\r\n \r\n {\r\n \"Name\": \"Phi-3-mini-4k-instruct-q4\",\r\n \"Description\": \"The Phi-3-Mini-4K-Instruct is a 3.8B parameters, lightweight, state-of-the-art open model trained with the Phi-3 datasets that includes both synthetic data and the filtered publicly available websites data with a focus on high-quality and reasoning dense properties.\",\r\n \"WebSite\": \"https://www.modelscope.cn/models/sangsq/Phi-3-mini-4k-instruct-gguf\",\r\n \"Version\": \"2024-07-08\",\r\n \"SystemPrompt\": \"You are a helpful AI assistant.\",\r\n \"ModelParams\": {\r\n \"ModelPath\": \"C:\\\\Users\\\\muehsig\\\\.cache\\\\lm-studio\\\\models\\\\lmstudio-community\\\\Phi-3.1-mini-128k-instruct-GGUF\\\\Phi-3.1-mini-128k-instruct-Q4_K_M.gguf\",\r\n \"ContextSize\": 4096,\r\n \"Seed\": 1337,\r\n \"GpuLayerCount\": 20\r\n },\r\n \"AntiPrompts\": [ \"<|user|>\", \"<|end|>\", \"<|endoftext|>\" ],\r\n \"WithTransform\": {\r\n \"HistoryTransform\": \"LLamaWorker.Transform.ZephyrHistoryTransform\"\r\n },\r\n \"ToolPrompt\": {\r\n \"Index\": 0,\r\n \"Lang\": \"en\"\r\n }\r\n }\r\n ],\r\n...\r\n```\r\n\r\nI also received an error with this code:\r\n\r\n```\r\n\r\nChatClient client = new(model: \"???\", \"xlm-qweqweqweW\",\r\n new OpenAI.OpenAIClientOptions()\r\n { Endpoint = new Uri(\"http://localhost:5114/v1\") });\r\n\r\nAsyncCollectionResult updates\r\n = client.CompleteChatStreamingAsync(\"Schreib eine Kindergeschichte mit 8 Sätzen.\");\r\n\r\nConsole.WriteLine($\"[ASSISTANT]:\");\r\nawait foreach (StreamingChatCompletionUpdate update in updates)\r\n{\r\n foreach (ChatMessageContentPart updatePart in update.ContentUpdate)\r\n {\r\n Console.Write(updatePart.Text);\r\n }\r\n}\r\n```\r\n\r\nThe very same code works without any issus when running against the LM Studio - has this something to do with those settings or is there an error in the OpenAI API implementation?\r\n\r\n![image](https://github.com/user-attachments/assets/0605e186-8bf9-4f3e-8b80-dbc2a88e6560)\r\n\r\nException:\r\n\r\n```\r\nSystem.NullReferenceException\r\n HResult=0x80004003\r\n Message=Object reference not set to an instance of an object.\r\n Source=OpenAI\r\n StackTrace:\r\n at OpenAI.Chat.StreamingChatCompletionUpdate.get_ContentUpdate()\r\n at Program.<
$>d__0.MoveNext() in C:\\Users\\muehsig\\source\\repos\\LlmTestApp\\LlmTestApp\\Program.cs:line 44\r\n```\r\n"}],"ResultType":"GitHubEvent"}},"RunOn":"2024-11-14T05:30:03.2595931Z","RunDurationInMilliseconds":2191} \ No newline at end of file