From f69f65add62fddf1255d95407548ea5c10abe25a Mon Sep 17 00:00:00 2001 From: Code-Inside-Bot Date: Mon, 22 Jan 2024 06:30:02 +0100 Subject: [PATCH] Sloader update on _data/Sloader.json --- _data/Sloader.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_data/Sloader.json b/_data/Sloader.json index 90875e5..1956205 100644 --- a/_data/Sloader.json +++ b/_data/Sloader.json @@ -1 +1 @@ -{"Data":{"Blog":{"FeedItems":[{"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 get any data out via our Active Directory component.

\n\n

Solution

\n\n

After some debugging and doubts about our functionality we (the admin of the customer and me) found the reason:\nOur code was running under a Windows Account that was very limted and couldn’t read those properties.

\n\n

If you have similar problems you might want to take a look in the AD User & Group management.

\n\n
    \n
  1. You need to active the advanced features:
  2. \n
\n\n

\"x\"

\n\n
    \n
  1. Now check the security tab, go to advanced view and add a new permission or change a existing one:
  2. \n
\n\n

\"x\"

\n\n
    \n
  1. Here you should be able to see a huge dialog with all available properties. Check if your user is able to read your target property
  2. \n
\n\n

\"x\"

\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},{"Title":"SQL collation problems","PublishedOn":"2021-11-24T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This week I deployed a new feature and tried it on different SQL databases and was a bit suprised that on one database this error message came up:

\n\n
Cannot resolve the collation conflict between \"Latin1_General_CI_AS\" and \"SQL_Latin1_General_CP1_CI_AS\" in the equal to operation.\n
\n\n

This was strange, because - at least in theory - all databases have the same schema and I was sure that each database had the same collation setting.

\n\n

Collations on columns

\n\n

Well… my theory was wrong and this SQL statement told me that “some” columns had a different collation.

\n\n
select sc.name, sc.collation_name from sys.columns sc\ninner join sys.tables t on sc.object_id=t.object_id\nwhere t.name='TABLENAME'\n
\n\n

As it turns out, some columns had the collation Latin1_General_CI_AS and some had SQL_Latin1_General_CP1_CI_AS. I’m still not sure why, but I needed to do something.

\n\n

How to change the collation

\n\n

To change the collation you can execute something like this:

\n\n
ALTER TABLE MyTable\nALTER COLUMN [MyColumn] NVARCHAR(200) COLLATE SQL_Latin1_General_CP1_CI_AS\n
\n\n

Unfortunately there are restrictions and you can’t change the collation if the column is referenced by any one of the following:

\n\n\n\n

Be aware: If you are not in control of the collation or if the collation is “fine” and you want to do this operation anyway, there might be a way to specify the collation in the SQL query.

\n\n

For more information you might want to check out this Microsoft Docs “Set or Change the Column Collation

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/11/24/sql-collations-problem/","RawContent":null,"Thumbnail":null},{"Title":"Microsoft Build 2021 session recommendations","PublishedOn":"2021-09-24T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

To be fair: Microsoft Build 2021 was some month ago, but the content might still be relevant today. Sooo… it took me a while, but here is a list of sessions that I found interesting. Some sessions are “better” and some “lighter”, the order doesn’t reflect that - that was just the order I watched those videos.

\n\n

The headline has a link to the video and below are some notes.

\n\n

Build cloud-native applications that run anywhere

\n\n\n\n

Build differentiated SaaS apps with the Microsoft Cloud

\n\n\n\n

[Build the next generation of collaborative apps for hybrid work

\n

](https://mybuild.microsoft.com/sessions/2915b9b6-6b45-430a-9df7-2671318e2161?source=sessions)

\n\n\n\n

[Mark Russinovich on Azure innovation and more!

\n

](https://mybuild.microsoft.com/sessions/b7d536c1-515f-476a-83d2-85b6cf14577a?source=sessions)

\n\n\n\n

[Learn how to build exciting apps across meetings, chats, and channels within or outside Microsoft Teams](

\n

https://mybuild.microsoft.com/sessions/512470be-15d3-4b50-b180-6532c8153931?source=sessions)

\n\n\n\n

What’s new for Windows desktop application development

\n\n\n\n

[Understand the ML process and embed models into apps

\n

](https://mybuild.microsoft.com/sessions/10930f2e-ad9c-460b-b91d-844d17a5a875?source=sessions)

\n\n\n\n

[The future of modern application development with .NET

\n

](https://mybuild.microsoft.com/sessions/76ebac39-517d-44da-a58e-df4193b5efa9?source=sessions)

\n\n\n\n

Scott Guthrie ‘Unplugged’ – Home Edition (Extended)

\n\n\n\n

Build your first web app with Blazor & Web Assembly

\n\n\n\n

Develop apps with the Microsoft Graph Toolkit

\n\n\n\n

Application Authentication in the Microsoft Identity platform

\n\n\n\n

[Double-click with Microsoft engineering leaders

\n

](https://mybuild.microsoft.com/sessions/08538f9b-e562-4d71-8b42-d240c3966ef0?source=sessions)

\n\n\n\n

[.NET 6 deep dive; what’s new and what’s coming

\n

](https://mybuild.microsoft.com/sessions/70d379f4-1173-4941-b389-8796152ec7b8?source=sessions)

\n\n\n\n

Hope this helps.

\n","Href":"https://blog.codeinside.eu/2021/09/24/build-2021-recommendation/","RawContent":null,"Thumbnail":null},{"Title":"Today I learned (sort of) 'fltmc' to inspect the IO request pipeline of Windows","PublishedOn":"2021-05-30T22:00:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The headline is obviously a big lie, because I followed this twitter conversation last year, but it’s still interesting to me and I wanted to write it somewhere down.

\n\n

Starting point was that Bruce Dawson (Google programmer) noticed, that building Chrome on Windows is slow for various reasons:

\n\n

Based on some twitter discussion about source-file length and build times two months ago I wrote a blog post. It's got real data based on Chromium's build, and includes animations of build-time improvements:https://t.co/lsLH8BNe48

— Bruce Dawson (Antifa) (@BruceDawson0xB) March 31, 2020
\n\n\n

Trentent Tye told him to disable the “filter driver”:

\n\n

disabling the filter driver makes it dead dead dead. Might be worth testing with the number and sizes of files you are dealing with. Even half a millisecond of processing time adds up when it runs against millions and millions of files.

— Trentent Tye (@TrententTye) April 1, 2020
\n\n\n

If you have never heard of a “filter driver” (like me :)), you might want to take a look here.

\n\n

To see the loaded filter driver on your machine try out this: Run fltmc (fltmc.exe) as admin.

\n\n

\"x\"

\n\n

Description:

\n\n

Each filter in the list sit in a pipe through which all IO requests bubble down and up. They see all IO requests, but ignore most. Ever wondered how Windows offers encrypted files, OneDrive/GDrive/DB file sync, storage quotas, system file protection, and, yes, anti-malware? ;)

— Rich Turner (@richturn_ms) April 2, 2020
\n\n\n

This makes more or less sense to me. I’m not really sure what to do with that information, but it’s cool (nerd cool, but anyway :)).

\n","Href":"https://blog.codeinside.eu/2021/05/30/fltmc-inspect-the-io-request-pipeline-of-windows/","RawContent":null,"Thumbnail":null},{"Title":"How to self host Google Fonts","PublishedOn":"2021-04-28T23:30:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Google Fonts are really nice and widely used. Typically Google Fonts consistes of the actual font file (e.g. woff, ttf, eot etc.) and some CSS, which points to those font files.

\n\n

In one of our applications, we used a HTML/CSS/JS - Bootstrap like theme and the theme linked some Google Fonts. The problem was, that we wanted to self host everything.

\n\n

After some research we discovered this tool: Google-Web-Fonts-Helper

\n\n

\"x\"

\n\n

Pick your font, select your preferred CSS option (e.g. if you need to support older browsers etc.) and download a complete .zip package. Extract those files and add them to your web project like any other static asset. (And check the font license!)

\n\n

The project site is on GitHub.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/04/28/how-to-self-host-google-fonts/","RawContent":null,"Thumbnail":null},{"Title":"Microsoft Graph: Read user profile and group memberships","PublishedOn":"2021-01-31T23:30:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In our application we have a background service, that “syncs” user data and group membership information to our database from the Microsoft Graph.

\n\n

The permission model:

\n\n

Programming against the Microsoft Graph is quite easy. There are many SDKS available, but understanding the permission model is hard.

\n\n

‘Directory.Read.All’ and ‘User.Read.All’:

\n\n

Initially we only synced the “basic” user data to our database, but then some customers wanted to reuse some other data already stored in the graph. Our app required the ‘Directory.Read.All’ permission, because we thought that this would be the “highest” permission - this is wrong!

\n\n

If you need “directory” information, e.g. memberships, the Directory.Read.All or Group.Read.All is a good starting point. But if you want to load specific user data, you might need to have the User.Read.All permission as well.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/01/31/microsoft-graph-read-user-profile-and-group-memberships/","RawContent":null,"Thumbnail":null},{"Title":"How to get all distribution lists of a user with a single LDAP query","PublishedOn":"2020-12-31T00:30:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In 2007 I wrote a blogpost how easy it is to get all “groups” of a given user via the tokenGroup attribute.

\n\n

Last month I had the task to check why “distribution list memberships” are not part of the result.

\n\n

The reason is simple:

\n\n

A pure distribution list (not security enabled) is not a security group and only security groups are part of the “tokenGroup” attribute.

\n\n

After some thoughts and discussions we agreed, that it would be good if we could enhance our function and treat distribution lists like security groups.

\n\n

How to get all distribution lists of a user?

\n\n

The get all groups of a given user might be seen as trivial, but the problem is, that groups can contain other groups. \nAs always, there are a couple of ways to get a “full flat” list of all group memberships.

\n\n

A stupid way would be to load all groups in a recrusive function - this might work, but will result in a flood of requests.

\n\n

A clever way would be to write a good LDAP query and let the Active Directory do the heavy lifting for us, right?

\n\n

1.2.840.113556.1.4.1941

\n\n

I found some sample code online with a very strange LDAP query and it turns out:\nThere is a “magic” ldap query called “LDAP_MATCHING_RULE_IN_CHAIN” and it does everything we are looking for:

\n\n
var getGroupsFilterForDn = $\"(&(objectClass=group)(member:1.2.840.113556.1.4.1941:= {distinguishedName}))\";\n                using (var dirSearch = CreateDirectorySearcher(getGroupsFilterForDn))\n                {\n                    using (var results = dirSearch.FindAll())\n                    {\n                        foreach (SearchResult result in results)\n                        {\n                            if (result.Properties.Contains(\"name\") && result.Properties.Contains(\"objectSid\") && result.Properties.Contains(\"groupType\"))\n                                groups.Add(new GroupResult() { Name = (string)result.Properties[\"name\"][0], GroupType = (int)result.Properties[\"groupType\"][0], ObjectSid = new SecurityIdentifier((byte[])result.Properties[\"objectSid\"][0], 0).ToString() });\n                        }\n                    }\n                }\n
\n\n

With a given distinguishedName of the target user, we can load all distribution and security groups (see below…) transitive!

\n\n

Combine tokenGroups and this

\n\n

During our testing we found some minor differences between the LDAP_MATCHING_RULE_IN_CHAIN and the tokenGroups approach. Some “system-level” security groups were missing with the LDAP_MATCHING_RULE_IN_CHAIN way. In our production code we use a combination of those two approaches and it seems to work.

\n\n

A full demo code how to get all distribution lists for a user can be found on GitHub.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/12/31/how-get-all-distribution-lists-of-a-user-with-a-single-ldap-query/","RawContent":null,"Thumbnail":null},{"Title":"Update AzureDevOps Server 2019 to AzureDevOps Server 2019 Update 1","PublishedOn":"2020-11-30T18:00:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We did this update in May 2020, but I forgot to publish the blogpost… so here we are

\n\n

Last year we updated to Azure DevOps Server 2019 and it went more or less smooth.

\n\n

In May we decided to update to the “newest” release at that time: Azure DevOps Server 2019 Update 1.1

\n\n

Setup

\n\n

Our AzureDevOps Server was running on a “new” Windows Server 2019 and everything was still kind of newish - so we just needed to update the AzureDevOps Server app.

\n\n

Update process

\n\n

The actual update was really easy, but we had some issues after the installation.

\n\n

Steps:

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

Aftermath

\n\n

We had some issues with our Build Agents - they couldn’t connect to the AzureDevOps Server:

\n\n
TF400813: Resource not available for anonymous access\n
\n\n

As a first “workaround” (and a nice enhancement) we switched from HTTP to HTTPS internally, but this didn’t solved the problem.

\n\n

The real reason was, that our “Azure DevOps Service User” didn’t had the required write permissions for this folder:

\n\n
C:\\ProgramData\\Microsoft\\Crypto\\RSA\\MachineKeys\n
\n\n

The connection issue went away, but now we introduced another problem: Our SSL Certificate was “self signed” (from our Domain Controller), so we need to register the agents like this:

\n\n
.\\config.cmd --gituseschannel --url https://.../tfs/ --auth Integrated --pool Default-VS2019 --replace --work _work\n
\n\n

The important parameter is -gituseschannel, which is needed when dealing with “self signed, but Domain ‘trusted’“-certificates.

\n\n

With this setting everything seemed to work as expected.

\n\n

Only node.js projects or toolings were “problematic”, because node.js itself don’t use the Windows Certificate Store.

\n\n

To resolve this, the root certificate from our Domain controller must be stored on the agent.

\n\n
  [Environment]::SetEnvironmentVariable(\"NODE_EXTRA_CA_CERTS\", \"C:\\SSLCert\\root-CA.pem\", \"Machine\") \n
\n\n

Summary

\n\n

The update itself was easy, but it took us some hours to configure our Build Agents. After the initial hiccup it went smooth from there - no issues and we are ready for the next update, which is already released.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/11/30/update-onprem-azuredevops-server-2019-to-azuredevops-server-2019-update1/","RawContent":null,"Thumbnail":null},{"Title":"DllRegisterServer 0x80020009 Error","PublishedOn":"2020-10-31T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Last week I had a very strange issue and the solution was really “easy”, but took me a while.

\n\n

Scenario

\n\n

For our products we build Office COM Addins with a C++ based “Shim” that boots up our .NET code (e.g. something like this.\nAs the nature of COM: It requires some pretty dumb registry entries to work and in theory our toolchain should “build” and automatically “register” the output.

\n\n

Problem

\n\n

The registration process just failed with a error message like that:

\n\n
The module xxx.dll was loaded but the call to DllRegisterServer failed with error code 0x80020009\n
\n\n

After some research you will find some very old stuff or only some general advises like in this Stackoverflow.com question, e.g. “run it as administrator”.

\n\n

The solution

\n\n

Luckily we had another project were we use the same approach and this worked without any issues. After comparing the files I notices some subtile differences: The file encoding was different!

\n\n

In my failing project some C++ files were encoded with UTF8-BOM. I changed everything to UTF8 and after this change it worked.

\n\n

My reaction:

\n\n
(╯°□°)╯︵ ┻━┻\n
\n\n

I’m not a C++ dev and I’m not even sure why some files had the wrong encoding in the first place. It “worked” - at least Visual Studio 2019 was able to build the stuff, but register it with “regsrv32” just failed.

\n\n

I needed some hours to figure that out.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/10/31/dllregisterserver-0x80020009-error/","RawContent":null,"Thumbnail":null},{"Title":"How to share an Azure subscription in a team","PublishedOn":"2020-09-29T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We at Sevitec are moving more and more workloads for us or our customers to Azure.

\n\n

So the basic question needs an answer:

\n\n

How can a team share an Azure subscription?

\n\n

Be aware: This approach works for us. There might be better options. If we do something stupid, just tell me in the comments or via email - help is appreciated.

\n\n

Step 1: Create a directory

\n\n

We have a “company directory” with a fully configured Azure Active Directory (incl. User sync between our OnPrem system, Office 365 licenses etc.).

\n\n

Our rule of thumb is: We create for each product team a individual directory and all team members are invited in the new directory.

\n\n

Keep in mind: A directory itself costs you nothing but might help you to keep things manageable.

\n\n

\"Create

\n\n

Step 2: Create a group

\n\n

This step might be optional, but all team members - except the “Administrator” - have the same rights and permissions in our company. To keep things simple, we created a group with all team members.

\n\n

\"Put

\n\n

Step 3: Create a subscription

\n\n

Now create a subscription. The typical “Pay-as-you-go” offer will work. Be aware that the user who creates the subscription is initially setup as the Administrator.

\n\n

\"Create

\n\n

Step 4: “Share” the subscription

\n\n

This is the most important step:

\n\n

You need to grant the individual users or the group (from step 2) the “Contributor” role for this subscription via the “Access control (IAM)”.\nThe hard part is to understand how those “Role assignment” affect the subscription. I’m not even sure if the “Contributor” is the best fit, but it works for us.

\n\n

\"Pick

\n\n

Summary

\n\n

I’m not really sure why such a basic concept is labeled so poorly but you really need to pick the correct role assignment and the other person should be able to use the subscription.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/09/29/how-to-share-an-azure-subscription-in-a-team/","RawContent":null,"Thumbnail":null},{"Title":"How to run a legacy WCF .svc Service on Azure AppService","PublishedOn":"2020-08-31T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Last month we wanted to run good old WCF powered service on Azures “App Service”.

\n\n

WCF… what’s that?

\n\n

If you are not familiar with WCF: Good! For the interested ones: WCF is or was a framework to build mostly SOAP based services in the .NET Framework 3.0 timeframe. Some parts where “good”, but most developers would call it a complex monster.

\n\n

Even in the glory days of WCF I tried to avoid it at all cost, but unfortunately I need to maintain a WCF based service.

\n\n

For the curious: The project template and the tech is still there. Search for “WCF”.

\n\n

\"VS

\n\n

The template will produce something like that:

\n\n

The actual “service endpoint” is the Service1.svc file.

\n\n

\"WCF

\n\n

Running on Azure: The problem

\n\n

Let’s assume we have a application with a .svc endpoint. In theory we can deploy this application to a standard Windows Server/IIS without major problems.

\n\n

Now we try to deploy this very same application to Azure AppService and this is the result after we invoke the service from the browser:

\n\n
\"The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.\" (HTTP Response was 404)\n
\n\n

Strange… very strange. In theory a blank HTTP 400 should appear, but not a HTTP 404. The service itself was not “triggered”, because we had some logging in place, but the request didn’t get to the actual service.

\n\n

After hours of debugging, testing and googling around I created a new “blank” WCF service from the Visual Studio template got the same error.

\n\n

The good news: It’s was not just my code something is blocking the request.

\n\n

After some hours I found a helpful switch in the Azure Portal and activated the “Failed Request tracing” feature (yeah… I could found it sooner) and I discovered this:

\n\n

\"Failed

\n\n

Running on Azure: The solution

\n\n

My initial thoughts were correct: The request was blocked. It was treated as “static content” and the actual WCF module was not mapped to the .svc extension.

\n\n

To “re-map” the .svc extension to the correct handler I needed to add this to the web.config:

\n\n
...\n<system.webServer>\n    ...\n\t<handlers>\n\t\t<remove name=\"svc-integrated\" />\n\t\t<add name=\"svc-integrated\" path=\"*.svc\" verb=\"*\" type=\"System.ServiceModel.Activation.HttpHandler\" resourceType=\"File\" preCondition=\"integratedMode\" />\n\t</handlers>\n</system.webServer>\n...\n\n
\n\n

With this configuration everything worked as expected on Azure AppService.

\n\n

Be aware:

\n\n

I’m really not 100% sure why this is needed in the first place. I’m also not 100% sure if the name svc-integrated is correct or important.

\n\n

This blogpost is a result of these tweets.

\n\n

That was a tough ride… Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/08/31/how-to-run-a-legacy-wcf-svc-service-on-azure-app-service/","RawContent":null,"Thumbnail":null},{"Title":"EWS, Exchange Online and OAuth with a Service Account","PublishedOn":"2020-07-31T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This week we had a fun experiment: We wanted to talk to Exchange Online via the “old school” EWS API, but in a “sane” way.

\n\n

But here is the full story:

\n\n

Our goal

\n\n

We wanted to access contact information via a web service from the organization, just like the traditional “Global Address List” in Exchange/Outlook. We knew that EWS was on option for the OnPrem Exchange, but what about Exchange Online?

\n\n

The big problem: Authentication is tricky. We wanted to use a “traditional” Service Account approach (think of username/password). Unfortunately the “basic auth” way will be blocked in the near future because of security concerns (makes sense TBH). There is an alternative approach available, but at first it seems not to work as we would like.

\n\n

So… what now?

\n\n

EWS is… old. Why?

\n\n

The Exchange Web Services are old, but still quite powerful and still supported for Exchange Online and OnPrem Exchanges. On the other hand we could use the Microsoft Graph, but - at least currently - there is not a single “contact” API available.

\n\n

To mimic the GAL we would need to query List Users and List orgContacts, which would be ok, but the “orgContacts” has a “flaw”. \n“Hidden” contacts (“msexchhidefromaddresslists”) are returned from this API and we thought that this might be a NoGo for our customers.

\n\n

Another argument for using EWS was, that we could support OnPrem and Online with one code base.

\n\n

Docs from Microsoft

\n\n

The good news is, that EWS and the Auth problem is more or less good documented here.

\n\n

There are two ways to authenticate against the Microsoft Graph or any Microsoft 365 API: Via “delegation” or via “application”.

\n\n

Delegation:

\n\n

Delegation means, that we can write a desktop app and all actions are executed in the name of the signed in user.

\n\n

Application:

\n\n

Application means, that the app itself can do some actions without any user involved.

\n\n

EWS and the application way

\n\n

At first we thought that we might need to use the “application” way.

\n\n

The good news is, that this was easy and worked. \nThe bad news is, that the application needs the EWS permission “full_access_as_app”, which means that our application can access all mailboxes from this tenant. This might be ok for certain apps, but this scared us.

\n\n

Back to the delegation way:

\n\n

EWS and the delegation way

\n\n

The documentation from Microsoft is good, but our “Service Account” usecase was not mentioned. In the example from Microsoft a user needs to manually login.

\n\n

Solution / TL;DR

\n\n

After some research I found the solution to use a “username/password” OAuth flow to access a single mailbox via EWS:

\n\n
    \n
  1. \n

    Follow the normal “delegate” steps from the Microsoft Docs

    \n
  2. \n
  3. \n

    Instead of this code, which will trigger the login UI:

    \n
  4. \n
\n\n
...\n// The permission scope required for EWS access\nvar ewsScopes = new string[] { \"https://outlook.office.com/EWS.AccessAsUser.All\" };\n\n// Make the interactive token request\nvar authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();\n...\n
\n\n

Use the “AcquireTokenByUsernamePassword” method:

\n\n
...\nvar cred = new NetworkCredential(\"UserName\", \"Password\");\nvar authResult = await pca.AcquireTokenByUsernamePassword(new string[] { \"https://outlook.office.com/EWS.AccessAsUser.All\" }, cred.UserName, cred.SecurePassword).ExecuteAsync();\n...\n
\n\n

To make this work you need to enable the “Treat application as public client” under “Authentication” > “Advanced settings” in our AAD Application because this uses the “Resource owner password credential flow”.

\n\n

Now you should be able to get the AccessToken and do some EWS magic.

\n\n

I posted a shorter version on Stackoverflow.com

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/07/31/ews-exchange-online-oauth-with-a-service-account/","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":"34926029849","Type":"IssuesEvent","CreatedAt":"2024-01-18T11:20:47","Actor":"robertmuehsig","Repository":"Azure/azure-sdk-for-net","Organization":"Azure","RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/Azure/azure-sdk-for-net/issues/41390","RelatedDescription":"Opened issue \"[BUG] \"-windows\" TargetFramework requires \"Microsoft.WindowsDesktop.App\" and can't be deployed to Azure\" (#41390) at Azure/azure-sdk-for-net","RelatedBody":"### Library name and version\n\nAzure.Identity 1.10.4\n\n### Describe the bug\n\nWhen you create a \"Windows\" specific Web Application like that:\r\n\r\n```\r\n\r\n\r\n \r\n net6.0-windows\r\n enable\r\n enable\r\n \r\n\r\n \r\n \r\n \r\n\r\n\r\n\r\n```\r\n\r\nThen the resulting project will require the WindowsDesktop runtime:\r\n\r\n```\r\n{\r\n \"runtimeOptions\": {\r\n \"tfm\": \"net6.0\",\r\n \"frameworks\": [\r\n {\r\n \"name\": \"Microsoft.NETCore.App\",\r\n \"version\": \"6.0.0\"\r\n },\r\n {\r\n \"name\": \"Microsoft.WindowsDesktop.App\",\r\n \"version\": \"6.0.0\"\r\n },\r\n {\r\n \"name\": \"Microsoft.AspNetCore.App\",\r\n \"version\": \"6.0.0\"\r\n }\r\n ],\r\n \"configProperties\": {\r\n \"System.GC.Server\": true,\r\n \"System.Reflection.Metadata.MetadataUpdater.IsSupported\": false,\r\n \"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization\": false\r\n }\r\n }\r\n}\r\n```\r\n\r\nReason is the dependency `Microsoft.Identity.Client`, which will add WebView2 and other stuff to the dependency tree:\r\n![image](https://github.com/Azure/azure-sdk-for-net/assets/756703/53bec7c9-9588-4c3d-be2d-540df82ccf5e)\r\n\r\nThe problem:\r\na) It was quite suprising that the target runtime dependency has changed.\r\nb) This WindowsDesktop Runtime is not available on Azure (e.g. App Service).\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n\n### Expected behavior\n\nIt seems wrong that the TargetFramework \"net6.0-windows\" is treated like \"the application will be run on a desktop environment\". \r\nI always thought that \"net6.0-windows\" is for applications that uses Windows Specific APIs, which might be a Web Application. With the current behavior we had to use \"net6.0\" (which is in the end a good thing, but feels a bit drastic just because one NuGet package has a weird feature backed in).\n\n### Actual behavior\n\nThe desktop runtime is required.\n\n### Reproduction Steps\n\n- Create a MVC App and use \"net6.0-windows\" (or net8.0-windows) as TargetFramework\r\n- Add Azure.Identity\r\n- Deploy to azure\r\n\r\nResult:\r\n```\r\nYou must install or update .NET to run this application.\r\n\r\nApp: C:\\inetpub\\wwwroot\\primedocs\\Service\\PrimeDocs.Service.Host.dll\r\nArchitecture: x64\r\nFramework: 'Microsoft.WindowsDesktop.App', version '6.0.0' (x64)\r\n.NET location: C:\\Program Files\\dotnet\\\r\n\r\nNo frameworks were found.\r\n\r\nLearn about framework resolution:\r\nhttps://aka.ms/dotnet/app-launch-failed\r\n\r\n```\r\n\n\n### Environment\n\nAzure App Service"},{"Id":"34715561356","Type":"IssuesEvent","CreatedAt":"2024-01-10T13:57:00","Actor":"oliverguhr","Repository":"prateekralhan/Deep-Punctuation-Corrector","Organization":null,"RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/prateekralhan/Deep-Punctuation-Corrector/issues/2","RelatedDescription":"Opened issue \"Use python package for long texts\" (#2) at prateekralhan/Deep-Punctuation-Corrector","RelatedBody":"Hi @prateekralhan,\r\nthanks for building this! Currently, you are using the [Pipleine API](https://github.com/prateekralhan/Deep-Punctuation-Corrector/blob/f7225b637db36559e2d7ae4509bf1fa103ca8f53/app_funcs.py#L9). This works only for up to 512 tokens, so you run into issues when you process a longer document. I built an inference API that uses the same model and can process infinitely long text:\r\n\r\n```\r\nfrom deepmultilingualpunctuation import PunctuationModel\r\n\r\nmodel = PunctuationModel()\r\ntext = \"A very long text\r\nresult = model.restore_punctuation(text)\r\nprint(result)\r\n\r\n```\r\n\r\nBest,\r\nOliver\r\n"},{"Id":"34150624271","Type":"PullRequestEvent","CreatedAt":"2023-12-13T20:21:45","Actor":"oliverguhr","Repository":"teaching-ml/2022","Organization":"teaching-ml","RawContent":null,"RelatedAction":"merged","RelatedUrl":"https://github.com/teaching-ml/2022/pull/16","RelatedDescription":"Merged pull request \"paper urls\" (#16) at teaching-ml/2022","RelatedBody":"They are here, the papers have been published!!!\r\n\r\n@kmkinnaird or @oliverguhr or @abhicc feel free to press the button and merge this."}],"ResultType":"GitHubEvent"}},"RunOn":"2024-01-21T05:30:02.1734298Z","RunDurationInMilliseconds":1333} \ No newline at end of file +{"Data":{"Blog":{"FeedItems":[{"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 get any data out via our Active Directory component.

\n\n

Solution

\n\n

After some debugging and doubts about our functionality we (the admin of the customer and me) found the reason:\nOur code was running under a Windows Account that was very limted and couldn’t read those properties.

\n\n

If you have similar problems you might want to take a look in the AD User & Group management.

\n\n
    \n
  1. You need to active the advanced features:
  2. \n
\n\n

\"x\"

\n\n
    \n
  1. Now check the security tab, go to advanced view and add a new permission or change a existing one:
  2. \n
\n\n

\"x\"

\n\n
    \n
  1. Here you should be able to see a huge dialog with all available properties. Check if your user is able to read your target property
  2. \n
\n\n

\"x\"

\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},{"Title":"SQL collation problems","PublishedOn":"2021-11-24T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This week I deployed a new feature and tried it on different SQL databases and was a bit suprised that on one database this error message came up:

\n\n
Cannot resolve the collation conflict between \"Latin1_General_CI_AS\" and \"SQL_Latin1_General_CP1_CI_AS\" in the equal to operation.\n
\n\n

This was strange, because - at least in theory - all databases have the same schema and I was sure that each database had the same collation setting.

\n\n

Collations on columns

\n\n

Well… my theory was wrong and this SQL statement told me that “some” columns had a different collation.

\n\n
select sc.name, sc.collation_name from sys.columns sc\ninner join sys.tables t on sc.object_id=t.object_id\nwhere t.name='TABLENAME'\n
\n\n

As it turns out, some columns had the collation Latin1_General_CI_AS and some had SQL_Latin1_General_CP1_CI_AS. I’m still not sure why, but I needed to do something.

\n\n

How to change the collation

\n\n

To change the collation you can execute something like this:

\n\n
ALTER TABLE MyTable\nALTER COLUMN [MyColumn] NVARCHAR(200) COLLATE SQL_Latin1_General_CP1_CI_AS\n
\n\n

Unfortunately there are restrictions and you can’t change the collation if the column is referenced by any one of the following:

\n\n\n\n

Be aware: If you are not in control of the collation or if the collation is “fine” and you want to do this operation anyway, there might be a way to specify the collation in the SQL query.

\n\n

For more information you might want to check out this Microsoft Docs “Set or Change the Column Collation

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/11/24/sql-collations-problem/","RawContent":null,"Thumbnail":null},{"Title":"Microsoft Build 2021 session recommendations","PublishedOn":"2021-09-24T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

To be fair: Microsoft Build 2021 was some month ago, but the content might still be relevant today. Sooo… it took me a while, but here is a list of sessions that I found interesting. Some sessions are “better” and some “lighter”, the order doesn’t reflect that - that was just the order I watched those videos.

\n\n

The headline has a link to the video and below are some notes.

\n\n

Build cloud-native applications that run anywhere

\n\n\n\n

Build differentiated SaaS apps with the Microsoft Cloud

\n\n\n\n

[Build the next generation of collaborative apps for hybrid work

\n

](https://mybuild.microsoft.com/sessions/2915b9b6-6b45-430a-9df7-2671318e2161?source=sessions)

\n\n\n\n

[Mark Russinovich on Azure innovation and more!

\n

](https://mybuild.microsoft.com/sessions/b7d536c1-515f-476a-83d2-85b6cf14577a?source=sessions)

\n\n\n\n

[Learn how to build exciting apps across meetings, chats, and channels within or outside Microsoft Teams](

\n

https://mybuild.microsoft.com/sessions/512470be-15d3-4b50-b180-6532c8153931?source=sessions)

\n\n\n\n

What’s new for Windows desktop application development

\n\n\n\n

[Understand the ML process and embed models into apps

\n

](https://mybuild.microsoft.com/sessions/10930f2e-ad9c-460b-b91d-844d17a5a875?source=sessions)

\n\n\n\n

[The future of modern application development with .NET

\n

](https://mybuild.microsoft.com/sessions/76ebac39-517d-44da-a58e-df4193b5efa9?source=sessions)

\n\n\n\n

Scott Guthrie ‘Unplugged’ – Home Edition (Extended)

\n\n\n\n

Build your first web app with Blazor & Web Assembly

\n\n\n\n

Develop apps with the Microsoft Graph Toolkit

\n\n\n\n

Application Authentication in the Microsoft Identity platform

\n\n\n\n

[Double-click with Microsoft engineering leaders

\n

](https://mybuild.microsoft.com/sessions/08538f9b-e562-4d71-8b42-d240c3966ef0?source=sessions)

\n\n\n\n

[.NET 6 deep dive; what’s new and what’s coming

\n

](https://mybuild.microsoft.com/sessions/70d379f4-1173-4941-b389-8796152ec7b8?source=sessions)

\n\n\n\n

Hope this helps.

\n","Href":"https://blog.codeinside.eu/2021/09/24/build-2021-recommendation/","RawContent":null,"Thumbnail":null},{"Title":"Today I learned (sort of) 'fltmc' to inspect the IO request pipeline of Windows","PublishedOn":"2021-05-30T22:00:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

The headline is obviously a big lie, because I followed this twitter conversation last year, but it’s still interesting to me and I wanted to write it somewhere down.

\n\n

Starting point was that Bruce Dawson (Google programmer) noticed, that building Chrome on Windows is slow for various reasons:

\n\n

Based on some twitter discussion about source-file length and build times two months ago I wrote a blog post. It's got real data based on Chromium's build, and includes animations of build-time improvements:https://t.co/lsLH8BNe48

— Bruce Dawson (Antifa) (@BruceDawson0xB) March 31, 2020
\n\n\n

Trentent Tye told him to disable the “filter driver”:

\n\n

disabling the filter driver makes it dead dead dead. Might be worth testing with the number and sizes of files you are dealing with. Even half a millisecond of processing time adds up when it runs against millions and millions of files.

— Trentent Tye (@TrententTye) April 1, 2020
\n\n\n

If you have never heard of a “filter driver” (like me :)), you might want to take a look here.

\n\n

To see the loaded filter driver on your machine try out this: Run fltmc (fltmc.exe) as admin.

\n\n

\"x\"

\n\n

Description:

\n\n

Each filter in the list sit in a pipe through which all IO requests bubble down and up. They see all IO requests, but ignore most. Ever wondered how Windows offers encrypted files, OneDrive/GDrive/DB file sync, storage quotas, system file protection, and, yes, anti-malware? ;)

— Rich Turner (@richturn_ms) April 2, 2020
\n\n\n

This makes more or less sense to me. I’m not really sure what to do with that information, but it’s cool (nerd cool, but anyway :)).

\n","Href":"https://blog.codeinside.eu/2021/05/30/fltmc-inspect-the-io-request-pipeline-of-windows/","RawContent":null,"Thumbnail":null},{"Title":"How to self host Google Fonts","PublishedOn":"2021-04-28T23:30:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Google Fonts are really nice and widely used. Typically Google Fonts consistes of the actual font file (e.g. woff, ttf, eot etc.) and some CSS, which points to those font files.

\n\n

In one of our applications, we used a HTML/CSS/JS - Bootstrap like theme and the theme linked some Google Fonts. The problem was, that we wanted to self host everything.

\n\n

After some research we discovered this tool: Google-Web-Fonts-Helper

\n\n

\"x\"

\n\n

Pick your font, select your preferred CSS option (e.g. if you need to support older browsers etc.) and download a complete .zip package. Extract those files and add them to your web project like any other static asset. (And check the font license!)

\n\n

The project site is on GitHub.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/04/28/how-to-self-host-google-fonts/","RawContent":null,"Thumbnail":null},{"Title":"Microsoft Graph: Read user profile and group memberships","PublishedOn":"2021-01-31T23:30:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In our application we have a background service, that “syncs” user data and group membership information to our database from the Microsoft Graph.

\n\n

The permission model:

\n\n

Programming against the Microsoft Graph is quite easy. There are many SDKS available, but understanding the permission model is hard.

\n\n

‘Directory.Read.All’ and ‘User.Read.All’:

\n\n

Initially we only synced the “basic” user data to our database, but then some customers wanted to reuse some other data already stored in the graph. Our app required the ‘Directory.Read.All’ permission, because we thought that this would be the “highest” permission - this is wrong!

\n\n

If you need “directory” information, e.g. memberships, the Directory.Read.All or Group.Read.All is a good starting point. But if you want to load specific user data, you might need to have the User.Read.All permission as well.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2021/01/31/microsoft-graph-read-user-profile-and-group-memberships/","RawContent":null,"Thumbnail":null},{"Title":"How to get all distribution lists of a user with a single LDAP query","PublishedOn":"2020-12-31T00:30:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

In 2007 I wrote a blogpost how easy it is to get all “groups” of a given user via the tokenGroup attribute.

\n\n

Last month I had the task to check why “distribution list memberships” are not part of the result.

\n\n

The reason is simple:

\n\n

A pure distribution list (not security enabled) is not a security group and only security groups are part of the “tokenGroup” attribute.

\n\n

After some thoughts and discussions we agreed, that it would be good if we could enhance our function and treat distribution lists like security groups.

\n\n

How to get all distribution lists of a user?

\n\n

The get all groups of a given user might be seen as trivial, but the problem is, that groups can contain other groups. \nAs always, there are a couple of ways to get a “full flat” list of all group memberships.

\n\n

A stupid way would be to load all groups in a recrusive function - this might work, but will result in a flood of requests.

\n\n

A clever way would be to write a good LDAP query and let the Active Directory do the heavy lifting for us, right?

\n\n

1.2.840.113556.1.4.1941

\n\n

I found some sample code online with a very strange LDAP query and it turns out:\nThere is a “magic” ldap query called “LDAP_MATCHING_RULE_IN_CHAIN” and it does everything we are looking for:

\n\n
var getGroupsFilterForDn = $\"(&(objectClass=group)(member:1.2.840.113556.1.4.1941:= {distinguishedName}))\";\n                using (var dirSearch = CreateDirectorySearcher(getGroupsFilterForDn))\n                {\n                    using (var results = dirSearch.FindAll())\n                    {\n                        foreach (SearchResult result in results)\n                        {\n                            if (result.Properties.Contains(\"name\") && result.Properties.Contains(\"objectSid\") && result.Properties.Contains(\"groupType\"))\n                                groups.Add(new GroupResult() { Name = (string)result.Properties[\"name\"][0], GroupType = (int)result.Properties[\"groupType\"][0], ObjectSid = new SecurityIdentifier((byte[])result.Properties[\"objectSid\"][0], 0).ToString() });\n                        }\n                    }\n                }\n
\n\n

With a given distinguishedName of the target user, we can load all distribution and security groups (see below…) transitive!

\n\n

Combine tokenGroups and this

\n\n

During our testing we found some minor differences between the LDAP_MATCHING_RULE_IN_CHAIN and the tokenGroups approach. Some “system-level” security groups were missing with the LDAP_MATCHING_RULE_IN_CHAIN way. In our production code we use a combination of those two approaches and it seems to work.

\n\n

A full demo code how to get all distribution lists for a user can be found on GitHub.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/12/31/how-get-all-distribution-lists-of-a-user-with-a-single-ldap-query/","RawContent":null,"Thumbnail":null},{"Title":"Update AzureDevOps Server 2019 to AzureDevOps Server 2019 Update 1","PublishedOn":"2020-11-30T18:00:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We did this update in May 2020, but I forgot to publish the blogpost… so here we are

\n\n

Last year we updated to Azure DevOps Server 2019 and it went more or less smooth.

\n\n

In May we decided to update to the “newest” release at that time: Azure DevOps Server 2019 Update 1.1

\n\n

Setup

\n\n

Our AzureDevOps Server was running on a “new” Windows Server 2019 and everything was still kind of newish - so we just needed to update the AzureDevOps Server app.

\n\n

Update process

\n\n

The actual update was really easy, but we had some issues after the installation.

\n\n

Steps:

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

\"x\"

\n\n

Aftermath

\n\n

We had some issues with our Build Agents - they couldn’t connect to the AzureDevOps Server:

\n\n
TF400813: Resource not available for anonymous access\n
\n\n

As a first “workaround” (and a nice enhancement) we switched from HTTP to HTTPS internally, but this didn’t solved the problem.

\n\n

The real reason was, that our “Azure DevOps Service User” didn’t had the required write permissions for this folder:

\n\n
C:\\ProgramData\\Microsoft\\Crypto\\RSA\\MachineKeys\n
\n\n

The connection issue went away, but now we introduced another problem: Our SSL Certificate was “self signed” (from our Domain Controller), so we need to register the agents like this:

\n\n
.\\config.cmd --gituseschannel --url https://.../tfs/ --auth Integrated --pool Default-VS2019 --replace --work _work\n
\n\n

The important parameter is -gituseschannel, which is needed when dealing with “self signed, but Domain ‘trusted’“-certificates.

\n\n

With this setting everything seemed to work as expected.

\n\n

Only node.js projects or toolings were “problematic”, because node.js itself don’t use the Windows Certificate Store.

\n\n

To resolve this, the root certificate from our Domain controller must be stored on the agent.

\n\n
  [Environment]::SetEnvironmentVariable(\"NODE_EXTRA_CA_CERTS\", \"C:\\SSLCert\\root-CA.pem\", \"Machine\") \n
\n\n

Summary

\n\n

The update itself was easy, but it took us some hours to configure our Build Agents. After the initial hiccup it went smooth from there - no issues and we are ready for the next update, which is already released.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/11/30/update-onprem-azuredevops-server-2019-to-azuredevops-server-2019-update1/","RawContent":null,"Thumbnail":null},{"Title":"DllRegisterServer 0x80020009 Error","PublishedOn":"2020-10-31T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Last week I had a very strange issue and the solution was really “easy”, but took me a while.

\n\n

Scenario

\n\n

For our products we build Office COM Addins with a C++ based “Shim” that boots up our .NET code (e.g. something like this.\nAs the nature of COM: It requires some pretty dumb registry entries to work and in theory our toolchain should “build” and automatically “register” the output.

\n\n

Problem

\n\n

The registration process just failed with a error message like that:

\n\n
The module xxx.dll was loaded but the call to DllRegisterServer failed with error code 0x80020009\n
\n\n

After some research you will find some very old stuff or only some general advises like in this Stackoverflow.com question, e.g. “run it as administrator”.

\n\n

The solution

\n\n

Luckily we had another project were we use the same approach and this worked without any issues. After comparing the files I notices some subtile differences: The file encoding was different!

\n\n

In my failing project some C++ files were encoded with UTF8-BOM. I changed everything to UTF8 and after this change it worked.

\n\n

My reaction:

\n\n
(╯°□°)╯︵ ┻━┻\n
\n\n

I’m not a C++ dev and I’m not even sure why some files had the wrong encoding in the first place. It “worked” - at least Visual Studio 2019 was able to build the stuff, but register it with “regsrv32” just failed.

\n\n

I needed some hours to figure that out.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/10/31/dllregisterserver-0x80020009-error/","RawContent":null,"Thumbnail":null},{"Title":"How to share an Azure subscription in a team","PublishedOn":"2020-09-29T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

We at Sevitec are moving more and more workloads for us or our customers to Azure.

\n\n

So the basic question needs an answer:

\n\n

How can a team share an Azure subscription?

\n\n

Be aware: This approach works for us. There might be better options. If we do something stupid, just tell me in the comments or via email - help is appreciated.

\n\n

Step 1: Create a directory

\n\n

We have a “company directory” with a fully configured Azure Active Directory (incl. User sync between our OnPrem system, Office 365 licenses etc.).

\n\n

Our rule of thumb is: We create for each product team a individual directory and all team members are invited in the new directory.

\n\n

Keep in mind: A directory itself costs you nothing but might help you to keep things manageable.

\n\n

\"Create

\n\n

Step 2: Create a group

\n\n

This step might be optional, but all team members - except the “Administrator” - have the same rights and permissions in our company. To keep things simple, we created a group with all team members.

\n\n

\"Put

\n\n

Step 3: Create a subscription

\n\n

Now create a subscription. The typical “Pay-as-you-go” offer will work. Be aware that the user who creates the subscription is initially setup as the Administrator.

\n\n

\"Create

\n\n

Step 4: “Share” the subscription

\n\n

This is the most important step:

\n\n

You need to grant the individual users or the group (from step 2) the “Contributor” role for this subscription via the “Access control (IAM)”.\nThe hard part is to understand how those “Role assignment” affect the subscription. I’m not even sure if the “Contributor” is the best fit, but it works for us.

\n\n

\"Pick

\n\n

Summary

\n\n

I’m not really sure why such a basic concept is labeled so poorly but you really need to pick the correct role assignment and the other person should be able to use the subscription.

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/09/29/how-to-share-an-azure-subscription-in-a-team/","RawContent":null,"Thumbnail":null},{"Title":"How to run a legacy WCF .svc Service on Azure AppService","PublishedOn":"2020-08-31T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

Last month we wanted to run good old WCF powered service on Azures “App Service”.

\n\n

WCF… what’s that?

\n\n

If you are not familiar with WCF: Good! For the interested ones: WCF is or was a framework to build mostly SOAP based services in the .NET Framework 3.0 timeframe. Some parts where “good”, but most developers would call it a complex monster.

\n\n

Even in the glory days of WCF I tried to avoid it at all cost, but unfortunately I need to maintain a WCF based service.

\n\n

For the curious: The project template and the tech is still there. Search for “WCF”.

\n\n

\"VS

\n\n

The template will produce something like that:

\n\n

The actual “service endpoint” is the Service1.svc file.

\n\n

\"WCF

\n\n

Running on Azure: The problem

\n\n

Let’s assume we have a application with a .svc endpoint. In theory we can deploy this application to a standard Windows Server/IIS without major problems.

\n\n

Now we try to deploy this very same application to Azure AppService and this is the result after we invoke the service from the browser:

\n\n
\"The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.\" (HTTP Response was 404)\n
\n\n

Strange… very strange. In theory a blank HTTP 400 should appear, but not a HTTP 404. The service itself was not “triggered”, because we had some logging in place, but the request didn’t get to the actual service.

\n\n

After hours of debugging, testing and googling around I created a new “blank” WCF service from the Visual Studio template got the same error.

\n\n

The good news: It’s was not just my code something is blocking the request.

\n\n

After some hours I found a helpful switch in the Azure Portal and activated the “Failed Request tracing” feature (yeah… I could found it sooner) and I discovered this:

\n\n

\"Failed

\n\n

Running on Azure: The solution

\n\n

My initial thoughts were correct: The request was blocked. It was treated as “static content” and the actual WCF module was not mapped to the .svc extension.

\n\n

To “re-map” the .svc extension to the correct handler I needed to add this to the web.config:

\n\n
...\n<system.webServer>\n    ...\n\t<handlers>\n\t\t<remove name=\"svc-integrated\" />\n\t\t<add name=\"svc-integrated\" path=\"*.svc\" verb=\"*\" type=\"System.ServiceModel.Activation.HttpHandler\" resourceType=\"File\" preCondition=\"integratedMode\" />\n\t</handlers>\n</system.webServer>\n...\n\n
\n\n

With this configuration everything worked as expected on Azure AppService.

\n\n

Be aware:

\n\n

I’m really not 100% sure why this is needed in the first place. I’m also not 100% sure if the name svc-integrated is correct or important.

\n\n

This blogpost is a result of these tweets.

\n\n

That was a tough ride… Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/08/31/how-to-run-a-legacy-wcf-svc-service-on-azure-app-service/","RawContent":null,"Thumbnail":null},{"Title":"EWS, Exchange Online and OAuth with a Service Account","PublishedOn":"2020-07-31T23:45:00+00:00","CommentsCount":0,"FacebookCount":0,"Summary":"\n

This week we had a fun experiment: We wanted to talk to Exchange Online via the “old school” EWS API, but in a “sane” way.

\n\n

But here is the full story:

\n\n

Our goal

\n\n

We wanted to access contact information via a web service from the organization, just like the traditional “Global Address List” in Exchange/Outlook. We knew that EWS was on option for the OnPrem Exchange, but what about Exchange Online?

\n\n

The big problem: Authentication is tricky. We wanted to use a “traditional” Service Account approach (think of username/password). Unfortunately the “basic auth” way will be blocked in the near future because of security concerns (makes sense TBH). There is an alternative approach available, but at first it seems not to work as we would like.

\n\n

So… what now?

\n\n

EWS is… old. Why?

\n\n

The Exchange Web Services are old, but still quite powerful and still supported for Exchange Online and OnPrem Exchanges. On the other hand we could use the Microsoft Graph, but - at least currently - there is not a single “contact” API available.

\n\n

To mimic the GAL we would need to query List Users and List orgContacts, which would be ok, but the “orgContacts” has a “flaw”. \n“Hidden” contacts (“msexchhidefromaddresslists”) are returned from this API and we thought that this might be a NoGo for our customers.

\n\n

Another argument for using EWS was, that we could support OnPrem and Online with one code base.

\n\n

Docs from Microsoft

\n\n

The good news is, that EWS and the Auth problem is more or less good documented here.

\n\n

There are two ways to authenticate against the Microsoft Graph or any Microsoft 365 API: Via “delegation” or via “application”.

\n\n

Delegation:

\n\n

Delegation means, that we can write a desktop app and all actions are executed in the name of the signed in user.

\n\n

Application:

\n\n

Application means, that the app itself can do some actions without any user involved.

\n\n

EWS and the application way

\n\n

At first we thought that we might need to use the “application” way.

\n\n

The good news is, that this was easy and worked. \nThe bad news is, that the application needs the EWS permission “full_access_as_app”, which means that our application can access all mailboxes from this tenant. This might be ok for certain apps, but this scared us.

\n\n

Back to the delegation way:

\n\n

EWS and the delegation way

\n\n

The documentation from Microsoft is good, but our “Service Account” usecase was not mentioned. In the example from Microsoft a user needs to manually login.

\n\n

Solution / TL;DR

\n\n

After some research I found the solution to use a “username/password” OAuth flow to access a single mailbox via EWS:

\n\n
    \n
  1. \n

    Follow the normal “delegate” steps from the Microsoft Docs

    \n
  2. \n
  3. \n

    Instead of this code, which will trigger the login UI:

    \n
  4. \n
\n\n
...\n// The permission scope required for EWS access\nvar ewsScopes = new string[] { \"https://outlook.office.com/EWS.AccessAsUser.All\" };\n\n// Make the interactive token request\nvar authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();\n...\n
\n\n

Use the “AcquireTokenByUsernamePassword” method:

\n\n
...\nvar cred = new NetworkCredential(\"UserName\", \"Password\");\nvar authResult = await pca.AcquireTokenByUsernamePassword(new string[] { \"https://outlook.office.com/EWS.AccessAsUser.All\" }, cred.UserName, cred.SecurePassword).ExecuteAsync();\n...\n
\n\n

To make this work you need to enable the “Treat application as public client” under “Authentication” > “Advanced settings” in our AAD Application because this uses the “Resource owner password credential flow”.

\n\n

Now you should be able to get the AccessToken and do some EWS magic.

\n\n

I posted a shorter version on Stackoverflow.com

\n\n

Hope this helps!

\n","Href":"https://blog.codeinside.eu/2020/07/31/ews-exchange-online-oauth-with-a-service-account/","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":"34926029849","Type":"IssuesEvent","CreatedAt":"2024-01-18T11:20:47","Actor":"robertmuehsig","Repository":"Azure/azure-sdk-for-net","Organization":"Azure","RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/Azure/azure-sdk-for-net/issues/41390","RelatedDescription":"Opened issue \"[BUG] \"-windows\" TargetFramework requires \"Microsoft.WindowsDesktop.App\" and can't be deployed to Azure\" (#41390) at Azure/azure-sdk-for-net","RelatedBody":"### Library name and version\n\nAzure.Identity 1.10.4\n\n### Describe the bug\n\nWhen you create a \"Windows\" specific Web Application like that:\r\n\r\n```\r\n\r\n\r\n \r\n net6.0-windows\r\n enable\r\n enable\r\n \r\n\r\n \r\n \r\n \r\n\r\n\r\n\r\n```\r\n\r\nThen the resulting project will require the WindowsDesktop runtime:\r\n\r\n```\r\n{\r\n \"runtimeOptions\": {\r\n \"tfm\": \"net6.0\",\r\n \"frameworks\": [\r\n {\r\n \"name\": \"Microsoft.NETCore.App\",\r\n \"version\": \"6.0.0\"\r\n },\r\n {\r\n \"name\": \"Microsoft.WindowsDesktop.App\",\r\n \"version\": \"6.0.0\"\r\n },\r\n {\r\n \"name\": \"Microsoft.AspNetCore.App\",\r\n \"version\": \"6.0.0\"\r\n }\r\n ],\r\n \"configProperties\": {\r\n \"System.GC.Server\": true,\r\n \"System.Reflection.Metadata.MetadataUpdater.IsSupported\": false,\r\n \"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization\": false\r\n }\r\n }\r\n}\r\n```\r\n\r\nReason is the dependency `Microsoft.Identity.Client`, which will add WebView2 and other stuff to the dependency tree:\r\n![image](https://github.com/Azure/azure-sdk-for-net/assets/756703/53bec7c9-9588-4c3d-be2d-540df82ccf5e)\r\n\r\nThe problem:\r\na) It was quite suprising that the target runtime dependency has changed.\r\nb) This WindowsDesktop Runtime is not available on Azure (e.g. App Service).\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n\n### Expected behavior\n\nIt seems wrong that the TargetFramework \"net6.0-windows\" is treated like \"the application will be run on a desktop environment\". \r\nI always thought that \"net6.0-windows\" is for applications that uses Windows Specific APIs, which might be a Web Application. With the current behavior we had to use \"net6.0\" (which is in the end a good thing, but feels a bit drastic just because one NuGet package has a weird feature backed in).\n\n### Actual behavior\n\nThe desktop runtime is required.\n\n### Reproduction Steps\n\n- Create a MVC App and use \"net6.0-windows\" (or net8.0-windows) as TargetFramework\r\n- Add Azure.Identity\r\n- Deploy to azure\r\n\r\nResult:\r\n```\r\nYou must install or update .NET to run this application.\r\n\r\nApp: C:\\inetpub\\wwwroot\\primedocs\\Service\\PrimeDocs.Service.Host.dll\r\nArchitecture: x64\r\nFramework: 'Microsoft.WindowsDesktop.App', version '6.0.0' (x64)\r\n.NET location: C:\\Program Files\\dotnet\\\r\n\r\nNo frameworks were found.\r\n\r\nLearn about framework resolution:\r\nhttps://aka.ms/dotnet/app-launch-failed\r\n\r\n```\r\n\n\n### Environment\n\nAzure App Service"},{"Id":"34715561356","Type":"IssuesEvent","CreatedAt":"2024-01-10T13:57:00","Actor":"oliverguhr","Repository":"prateekralhan/Deep-Punctuation-Corrector","Organization":null,"RawContent":null,"RelatedAction":"opened","RelatedUrl":"https://github.com/prateekralhan/Deep-Punctuation-Corrector/issues/2","RelatedDescription":"Opened issue \"Use python package for long texts\" (#2) at prateekralhan/Deep-Punctuation-Corrector","RelatedBody":"Hi @prateekralhan,\r\nthanks for building this! Currently, you are using the [Pipleine API](https://github.com/prateekralhan/Deep-Punctuation-Corrector/blob/f7225b637db36559e2d7ae4509bf1fa103ca8f53/app_funcs.py#L9). This works only for up to 512 tokens, so you run into issues when you process a longer document. I built an inference API that uses the same model and can process infinitely long text:\r\n\r\n```\r\nfrom deepmultilingualpunctuation import PunctuationModel\r\n\r\nmodel = PunctuationModel()\r\ntext = \"A very long text\r\nresult = model.restore_punctuation(text)\r\nprint(result)\r\n\r\n```\r\n\r\nBest,\r\nOliver\r\n"},{"Id":"34150624271","Type":"PullRequestEvent","CreatedAt":"2023-12-13T20:21:45","Actor":"oliverguhr","Repository":"teaching-ml/2022","Organization":"teaching-ml","RawContent":null,"RelatedAction":"merged","RelatedUrl":"https://github.com/teaching-ml/2022/pull/16","RelatedDescription":"Merged pull request \"paper urls\" (#16) at teaching-ml/2022","RelatedBody":"They are here, the papers have been published!!!\r\n\r\n@kmkinnaird or @oliverguhr or @abhicc feel free to press the button and merge this."}],"ResultType":"GitHubEvent"}},"RunOn":"2024-01-22T05:30:02.1322559Z","RunDurationInMilliseconds":1224} \ No newline at end of file