<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dries Deboosere</title>
    <description>The latest articles on DEV Community by Dries Deboosere (@drieze).</description>
    <link>https://dev.to/drieze</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F170645%2F012e79b4-64c6-4f40-9df4-a3dae5327f80.JPEG</url>
      <title>DEV Community: Dries Deboosere</title>
      <link>https://dev.to/drieze</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/drieze"/>
    <language>en</language>
    <item>
      <title>How to auto deploy an ASP.NET 6.0 application to Digital Ocean App</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Sun, 09 Apr 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-auto-deploy-an-aspnet-60-application-to-digital-ocean-app-11je</link>
      <guid>https://dev.to/drieze/how-to-auto-deploy-an-aspnet-60-application-to-digital-ocean-app-11je</guid>
      <description>&lt;p&gt;Automatic deploy your ASP.NET 6.0 GitHub repository to an DigitalOcean App. Auto-deploy your app from your GitHub source by committing and pushing your changes to your GitHub repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a new ASP.NET 6.0 web application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open your Visual Studio and create a new ASP.NET MVC application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bS1RckWx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bS1RckWx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-13.png" alt="" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In my case I choose .NET 6.0 framework&lt;/li&gt;
&lt;li&gt;Check the &lt;strong&gt;Enable Docker&lt;/strong&gt; checkbox.&lt;/li&gt;
&lt;li&gt;Create the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--deMKiohi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--deMKiohi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-14.png" alt="" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the &lt;code&gt;Views/Home/Index.cshtml&lt;/code&gt; file and add the following code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Oit2eFSD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Oit2eFSD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-29.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a new GitHub repository from our project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now we'll create a new GitHub repository from our project. You can do this by clicking on the &lt;strong&gt;Add to Source Control&lt;/strong&gt; option.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WD2qYS5u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WD2qYS5u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-15.png" alt="" width="502" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Git&lt;/strong&gt; as your source control provider.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0vbpZjiZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0vbpZjiZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-16.png" alt="" width="265" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the next screen you can fill in the details of your repository. In my case I will use &lt;strong&gt;DigitalOceanDeploymentDemo&lt;/strong&gt; as the name for my new repository. You can use the name of your repository and decide if you want to make it public or private, if you need a README, ...&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Create and Push&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9VKns5sX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9VKns5sX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-17.png" alt="" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now you can see that the repository is created and the project is pushed to the repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t3xmPb3R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t3xmPb3R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-18.png" alt="" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Move the Dockerfile to the root of the project
&lt;/h2&gt;

&lt;p&gt;It's important that the Dockerfile is in the root of the project. So we'll move the Dockerfile to the root of the project.&lt;/p&gt;

&lt;p&gt;The easiest way to do this is to right-click on the Dockerfile in Visual Studio Solution Explorer and choose the &lt;strong&gt;Open Containing Folder&lt;/strong&gt; option.&lt;/p&gt;

&lt;p&gt;Now you can move the Dockerfile to the root of the project from the Windows Explorer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xJMNwCLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xJMNwCLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-19.png" alt="" width="671" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commit and push the changes to GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8yn9dq06--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8yn9dq06--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-20.png" alt="" width="457" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it's time to create our Digital Ocean App.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Digital Ocean account
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;First of all, you'll need a Digital Ocean account. If you don't have an DO account than you can create an account with this &lt;a href="https://m.do.co/c/1f04571a4bbe"&gt;referral link&lt;/a&gt; and you'll get $200 credits to spend in the next 60 days. &lt;em&gt;(And you'll help me to keep this blog running.)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Digital Ocean App
&lt;/h2&gt;

&lt;p&gt;DigitalOcean App Platform is a Platform-as-a-Service (PaaS) offering that makes it easy for developers to deploy their C# asp.net core applications to DigitalOcean servers. With App Platform, you can publish your code directly from your GitHub repository without worrying about the underlying infrastructure. This means that you can focus on building your app and let DigitalOcean take care of the rest!&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Digital Ocean App
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Now you'll need to go to the Digital Ocean dashboard and create a new App. You can do this by clicking on the "Apps" menu item.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y0fk6Lnc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y0fk6Lnc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-01.png" alt="" width="194" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the "Create App" button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XiSbu3Cd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XiSbu3Cd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-02.png" alt="" width="552" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Digital Ocean App configuration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It's time to configure the Digital Ocean App. As &lt;strong&gt;Service Provider&lt;/strong&gt; we will use &lt;strong&gt;GitHub&lt;/strong&gt; , because we want to deploy our ASP.NET Docker image from a GitHub repository. So we select &lt;strong&gt;GitHub&lt;/strong&gt; as our service provider.&lt;/li&gt;
&lt;li&gt;Now click on the &lt;strong&gt;Manage Access&lt;/strong&gt; button to grant Digital Ocean access to your GitHub repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bae9h96p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bae9h96p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-03.png" alt="" width="800" height="625"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the next screen, choose &lt;strong&gt;Only select repositories&lt;/strong&gt; and select the repository that you want to use. In this demo, we will use the &lt;strong&gt;Drieze/DigitalOceanDeploymentDemo&lt;/strong&gt; repository.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Install &amp;amp; Authorize&lt;/strong&gt; button to grant Digital Ocean access to your GitHub repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JNv1Ffzg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JNv1Ffzg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-04.png" alt="" width="527" height="1038"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now you can choose your granted repository in the dropdown menu below &lt;strong&gt;Repository&lt;/strong&gt;. Choose the repository that you want to use. In my case it's the &lt;em&gt;Drieze/DigitalOceanDeploymentDemo&lt;/em&gt; repository.&lt;/li&gt;
&lt;li&gt;Next you have to choose the &lt;strong&gt;branch&lt;/strong&gt; on your repository that you want to be published every time you make an update on the selected branch. In my case it's the &lt;em&gt;master&lt;/em&gt; branch.&lt;/li&gt;
&lt;li&gt;Leave the &lt;strong&gt;Source Directory&lt;/strong&gt; on the root folder &lt;code&gt;/&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;Make sure that the &lt;strong&gt;Autodeploy&lt;/strong&gt; checkbox is checked. It should be checked by default.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Next&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---zNjim1U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---zNjim1U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-05.png" alt="" width="800" height="732"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now you see a summary of your app. As you can see I get a random name for my app (&lt;em&gt;clownfish-app&lt;/em&gt;), yours can be different.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LjKBITkr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LjKBITkr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-06.png" alt="" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now click on the &lt;strong&gt;Edit&lt;/strong&gt; button to edit the app configuration. It's important that we change the port number. We need to change the port number to &lt;strong&gt;80&lt;/strong&gt;. Because we want to use the default port for HTTP traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--amkG-9RA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--amkG-9RA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-21.png" alt="" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the &lt;strong&gt;Edit&lt;/strong&gt; button in the &lt;strong&gt;HTTP Port&lt;/strong&gt; section.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ay46L9L9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ay46L9L9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-22.png" alt="" width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the port number to &lt;strong&gt;80&lt;/strong&gt; and click on the &lt;strong&gt;Save&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Back&lt;/strong&gt; button to go back to the summary screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0MhJwMDk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0MhJwMDk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-23.png" alt="" width="800" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you want, you can add an addiontal resource, but in this demo we will not add any additional resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the &lt;strong&gt;Next&lt;/strong&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I don't have any enivronment variables, so I will skip this step. And click on &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_5v4c1Ic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_5v4c1Ic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-07.png" alt="" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the next screen you'll see a summary of your app. If everything is correct, click on the &lt;strong&gt;Next&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4EqIh1qL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4EqIh1qL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-08.png" alt="" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the next screen you can do a review of your app. Scroll down to change the &lt;strong&gt;Billing&lt;/strong&gt; plan.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Edit Plan&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LWNdK4EZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LWNdK4EZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-10.png" alt="" width="800" height="1041"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can choose the plan that you want. If you want to use some &lt;strong&gt;free credits&lt;/strong&gt; , you can use this &lt;a href="https://m.do.co/c/1f04571a4bbe"&gt;referral link&lt;/a&gt; to get $200 credits to spend in the next 60 days.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;I choose the &lt;strong&gt;Basic&lt;/strong&gt; plan.&lt;/li&gt;
&lt;li&gt;And changed the Size to &lt;strong&gt;$5.00/mo - Basic&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Back&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--haJHCKs6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--haJHCKs6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-09.png" alt="" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now click on the &lt;strong&gt;Create Resources&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VRzjBsTh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VRzjBsTh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-11.png" alt="" width="800" height="996"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now you can see that your app is being deployed. It can take a few minutes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wgqtppuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wgqtppuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-12.png" alt="" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the Docker image
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Now you can see that the Docker image is being built. It can take a few minutes.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Go to Build Logs&lt;/strong&gt; button to see the build logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xj7i51-0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xj7i51-0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-24.png" alt="" width="800" height="740"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you see an error that the Dockerfile is not found, you can check if the Dockerfile is in the root folder of your repository.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;After a succesfull build, your app is gonna be deployed.&lt;/li&gt;
&lt;li&gt;Now click on the &lt;strong&gt;Live App&lt;/strong&gt; button to see your app live.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qOFVUSZ5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-25.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qOFVUSZ5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-25.png" alt="" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now you can see that your app is live and running on Digital Ocean.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vLXvw1mY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vLXvw1mY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-26.png" alt="" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the GitHub repository
&lt;/h3&gt;

&lt;p&gt;Now it's time to make a change to the GitHub repository. We will change the text on the home page. I'll add a new p-tag with the text "Test".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DbDLXKbc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DbDLXKbc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-30.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now we need to commit the changes to the GitHub repository.&lt;/li&gt;
&lt;li&gt;Our Digital Ocean App will detect the changes and will build a new Docker image and deploy the new Docker image to our Digital Ocean App.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NX3uUnd5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-27.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NX3uUnd5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-27.png" alt="" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the build and deployment is done you can see that the text on the home page is changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cw_Il5BZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cw_Il5BZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-auto-deploy-aspnet-60-app-docker-image-to-digital-ocean-app/how-to-deploy-asp-net-docker-image-to-digital-ocean-28.png" alt="" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub repository for this demo
&lt;/h2&gt;

&lt;p&gt;You can find the GitHub repository for this demo &lt;a href="https://github.com/Drieze/driesdeboosere.dev.demos/tree/master/DigitalOceanAppDeployment"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>digitalocean</category>
      <category>deploy</category>
      <category>github</category>
    </item>
    <item>
      <title>How to add cookie consent in ASP.NET 6</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Fri, 07 Apr 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-add-cookie-consent-in-aspnet-6-1b2e</link>
      <guid>https://dev.to/drieze/how-to-add-cookie-consent-in-aspnet-6-1b2e</guid>
      <description>&lt;p&gt;Let's configure our &lt;code&gt;Program.cs&lt;/code&gt; class by add this configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.Configure(options =&amp;gt;
{
    // This lambda determines whether user consent for non-essential 
    // cookies is needed for a given request.
    options.CheckConsentNeeded = context =&amp;gt; true;

    options.MinimumSameSitePolicy = SameSiteMode.None;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add following code in your &lt;code&gt;Program&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.UseCookiePolicy();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure(options =&amp;gt;
{
    // This lambda determines whether user consent for non-essential 
    // cookies is needed for a given request.
    options.CheckConsentNeeded = context =&amp;gt; true;

    options.MinimumSameSitePolicy = SameSiteMode.None;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a new Razor page in the &lt;code&gt;Shared&lt;/code&gt; folder with the name: `_CookieConsentPartial.cshtml' and add following code in this new page:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
@using Microsoft.AspNetCore.Http.Features&lt;/p&gt;

&lt;p&gt;@{&lt;br&gt;
    var consentFeature = Context.Features.Get();&lt;br&gt;
    var showBanner = !consentFeature?.CanTrack ?? false;&lt;br&gt;
    var cookieString = consentFeature?.CreateConsentCookie();&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;@if (showBanner)&lt;br&gt;
{&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Use this space to summarize your privacy and cookie use policy. Learn More.

        Accept



    (function () {
        var button = document.querySelector("#cookieConsent button[data-cookie-string]");
        button.addEventListener("click", function (event) {
            document.cookie = button.dataset.cookieString;
        }, false);
    })();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now add the &lt;code&gt;partial&lt;/code&gt; tag-helper in your `_Layout.cshtml' page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

  @RenderBody()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can place this partial tag-helper anywhere you want in your HTML code.&lt;/p&gt;

&lt;p&gt;If you run your web application you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P0md0jHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-add-cookie-consent-in-aspnet-6/how-to-add-cookie-consent-in-aspnet-6-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P0md0jHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://driesdeboosere.dev/blog/how-to-add-cookie-consent-in-aspnet-6/how-to-add-cookie-consent-in-aspnet-6-01.png" alt="cookie consent example" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click &lt;strong&gt;Accept&lt;/strong&gt; then you'll see the cookie message disappear. Refresh your page and you'll see that the message doesn't come back.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>How to enable HTTP/2 on NGINX</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Tue, 10 Jan 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-enable-http2-on-nginx-33nb</link>
      <guid>https://dev.to/drieze/how-to-enable-http2-on-nginx-33nb</guid>
      <description>&lt;p&gt;In this post, I'll explain how you can setup your NGINX for HTTP/2.&lt;/p&gt;

&lt;p&gt;Go to your &lt;code&gt;nginx.conf&lt;/code&gt; or &lt;code&gt;default&lt;/code&gt; configuration file. In my case I'll need to change my NGINX default configuration file;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano /etc/nginx/sites-available/default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should look something like this;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name driesdeboosere.dev *.driesdeboosere.dev;
    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/driesdeboosere.dev/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/driesdeboosere.dev/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;http2&lt;/code&gt; after &lt;code&gt;ssl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
listen 443 ssl http2; # managed by Certbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now save your changes to the NGINX config file and reload NGINX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well done! Now your NGINX server uses HTTP/2!&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>ubuntu</category>
      <category>http2</category>
      <category>howto</category>
    </item>
    <item>
      <title>How to add text to an image with C# in dotnet</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Wed, 04 Jan 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-add-text-to-an-image-with-c-in-dotnet-6di</link>
      <guid>https://dev.to/drieze/how-to-add-text-to-an-image-with-c-in-dotnet-6di</guid>
      <description>&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;In this demo, we will add some text to an existing image.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We type some &lt;em&gt;Lorem Ipsum&lt;/em&gt; text in a textarea:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Mjeusjb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Mjeusjb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-01.png" alt="" width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;And add the text to an image:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4be0qHjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4be0qHjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-02.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a new application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a new dotnet application, in this demo, we'll use an ASP.NET Core MVC project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7S3kH_0T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7S3kH_0T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-03.png" alt="" width="501" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give your project and solution a name:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bwHXWo4g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bwHXWo4g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-04.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose your framework, in my case it's .NET6.0, and click on &lt;strong&gt;Create&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eq4Uc_xb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eq4Uc_xb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-05.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing an image
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Time for us to choose an image. I found a free image online from an aged paper that you can download &lt;a href="https://www.freeimages.com/photo/aged-papers-1142460"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mthZ5H_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-06.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mthZ5H_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-06.jpg" alt="" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now it's time to create a folder in our project. Give this folder the name of &lt;code&gt;Resources&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copy the image to this folder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P4Qbk3Ug--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4Qbk3Ug--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-08.png" alt="" width="155" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This image needs to be built as a resource and needs to be copied to the output directory. So right-click the image and choose properties;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ntc_0tS3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ntc_0tS3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-09.png" alt="" width="392" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the &lt;em&gt;Build Action&lt;/em&gt; to &lt;strong&gt;Resource&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Change the &lt;em&gt;Copy to Output Directory&lt;/em&gt; to &lt;strong&gt;Copy if newer&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gZHKuaax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gZHKuaax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-10.png" alt="" width="421" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose a font
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now it's time to choose a font. Because the image is an aged paper we'll use a handwriting font. For this demo, we'll use the &lt;strong&gt;Autography&lt;/strong&gt; font that you can download &lt;a href="https://www.dafont.com/autography.font"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kvosCLzI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kvosCLzI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-07.png" alt="" width="799" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Place the otf-file in the Resources folder and change the &lt;em&gt;Build Action&lt;/em&gt; to &lt;strong&gt;Resource&lt;/strong&gt; and the &lt;em&gt;Copy to Output Directory&lt;/em&gt; to &lt;strong&gt;Copy if newer&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1li_VZBs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1li_VZBs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-11.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add text to image with C
&lt;/h2&gt;

&lt;p&gt;Finally, the moment where we can write some code!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an &lt;code&gt;IndexViewModel&lt;/code&gt; in the &lt;strong&gt;Models/Home&lt;/strong&gt; folder
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace AddTextToImage.Mvc.Models.Home
{
    public class IndexViewModel
    {
        public string? Text { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;ResultViewModel&lt;/code&gt; in the &lt;strong&gt;Models/Home&lt;/strong&gt; folder
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace AddTextToImage.Mvc.Models.Home
{
    public class ResultViewModel
    {
        public string Path { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Change the &lt;code&gt;Index&lt;/code&gt; action method in the &lt;code&gt;HomeController&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public IActionResult Index()
{
    IndexViewModel model = new IndexViewModel();
    return View(model);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Change the &lt;code&gt;Index&lt;/code&gt; view from the &lt;strong&gt;Home&lt;/strong&gt; folder
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@model AddTextToImage.Mvc.Models.Home.IndexViewModel

@{
    ViewData["Title"] = "Home Page";
}


        Text

        We'll never share your text with anyone else and do not store your text.

    Create image

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add two &lt;a href="https://github.com/SixLabors/ImageSharp"&gt;SixLabors ImageSharp&lt;/a&gt; NuGet packages to the project:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;&amp;gt;
&amp;lt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add an &lt;code&gt;Index&lt;/code&gt; with an &lt;code&gt;[HttpPost]&lt;/code&gt; attribute
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpPost]
public IActionResult Index(IndexViewModel model)
{
    var downloadsPath = string.Empty;
    using (var img = SixLabors.ImageSharp.Image.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", paper.jpg")))
    {
        FontCollection collection = new();
        var path = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources")); // Path to the Resources folder
        FontFamily family = collection.Add(Path.Combine(path, "Autography.otf")); // Path incl filename for our font
        Font font = family.CreateFont(80, FontStyle.Regular); // Fontsize is 80 and Fontstyle is Regular

        // The options are optional
        TextOptions options = new(font)
        {
            Origin = new PointF(150, 100), // Set the rendering origin with the x and y coordinates
            TabWidth = 8, // A tab renders as 8 spaces wide
            WrappingLength = 1400, // Greater than zero so we will word wrap at 1400 pixels wide
            HorizontalAlignment = HorizontalAlignment.Left,
        };

        IBrush brush = Brushes.Solid(Color.Black); // Font color

        string text = model.Text;

        downloadsPath = Path.Combine(_webHostEnvironment.WebRootPath, "images", "paper-with-text.jpg");

        img.Mutate(x =&amp;gt; x.DrawText(options, text, brush)); // Write text on image
        img.Save(Path.Combine(downloadsPath)); // Save image to a folder
    }
    ResultViewModel resultModel = new ResultViewModel();
    resultModel.Path = "/images/paper-with-text.jpg";
    return RedirectToAction("Result", resultModel);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inject &lt;code&gt;IWebHostEnviroment&lt;/code&gt; in the &lt;code&gt;HomeController&lt;/code&gt; constructor
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private readonly ILogger _logger;
private readonly IWebHostEnvironment _webHostEnvironment;

public HomeController(ILogger logger, IWebHostEnvironment webHostEnvironment)
{
    _logger = logger;
    _webHostEnvironment = webHostEnvironment;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;Result&lt;/code&gt; method in the &lt;code&gt;HomeController&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public IActionResult Result(ResultViewModel model)
{
    return View(model);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;Result&lt;/code&gt; View in the &lt;strong&gt;Views/Home&lt;/strong&gt; folder
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@model AddTextToImage.Mvc.Models.Home.ResultViewModel

@{
    ViewData["Title"] = "Paper with our text";
}

    @ViewData["Title"]






&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run our application
&lt;/h2&gt;

&lt;p&gt;Now it's time to run our application, so start the project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter some text in the text-area. Some Lorem Ipsum by example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Mjeusjb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Mjeusjb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-01.png" alt="" width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on &lt;strong&gt;Create image&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;See the result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4be0qHjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4be0qHjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://driesdeboosere.dev/blog/how-to-add-text-to-image-in-dot-net/how-to-add-text-to-image-in-dot-net-02.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tweaks
&lt;/h2&gt;

&lt;p&gt;You can tinker around with all the different settings that the ImageSharp package offers, you can change by example&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;font size&lt;/li&gt;
&lt;li&gt;font family&lt;/li&gt;
&lt;li&gt;font type&lt;/li&gt;
&lt;li&gt;font color&lt;/li&gt;
&lt;li&gt;where the text needs to be aligned&lt;/li&gt;
&lt;li&gt;horizontal alignment&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Source
&lt;/h2&gt;

&lt;p&gt;You can find the &lt;a href="https://github.com/Drieze/driesdeboosere.dev.demos"&gt;GitHub repository&lt;/a&gt; here.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>image</category>
      <category>imagesharp</category>
    </item>
    <item>
      <title>How to redirect www to non-www with Nginx</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Sat, 14 Aug 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-redirect-www-to-non-www-with-nginx-161g</link>
      <guid>https://dev.to/drieze/how-to-redirect-www-to-non-www-with-nginx-161g</guid>
      <description>&lt;p&gt;When you have a website or web application behind a domain, then your users can access your website by the domain name and the &lt;strong&gt;www&lt;/strong&gt; sub domain.&lt;/p&gt;

&lt;p&gt;For example, this website is accessible through &lt;a href="https://driesdeboosere.dev" rel="noopener noreferrer"&gt;https://driesdeboosere.dev&lt;/a&gt; &lt;em&gt;(without www sub domain)&lt;/em&gt; and &lt;a href="https://www.driesdeboosere.dev" rel="noopener noreferrer"&gt;https://www.driesdeboosere.dev&lt;/a&gt; &lt;em&gt;(with &lt;strong&gt;www&lt;/strong&gt; sub domain)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When a user goes to &lt;a href="https://www.driesdeboosere.dev" rel="noopener noreferrer"&gt;https://www.driesdeboosere.dev&lt;/a&gt; then that user will be redirected to &lt;a href="https://driesdeboosere.dev" rel="noopener noreferrer"&gt;https://driesdeboosere.dev&lt;/a&gt; (_without the &lt;strong&gt;www&lt;/strong&gt; _).&lt;/p&gt;

&lt;p&gt;To achieve this on a Nginx server you'll need to do the following:&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure DNS
&lt;/h2&gt;

&lt;p&gt;In order to set up this redirect, &lt;code&gt;www.driesdeboosere.dev&lt;/code&gt; to &lt;code&gt;driesdeboosere.dev&lt;/code&gt; or visa versa, you must have an A record for the domain (driesdeboosere.dev) and an A record for the sub domain (&lt;a href="http://www.driesdeboosere.dev" rel="noopener noreferrer"&gt;www.driesdeboosere.dev&lt;/a&gt;).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an A record for your domain name (e.g. &lt;code&gt;driesdeboosere.dev&lt;/code&gt;) and set the IP address to the public IP address of your Nginx server (e.g. &lt;code&gt;165.22.205.49&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Next, add another A record for your sub domain (e.g. &lt;code&gt;www.driesdeboosere.dev&lt;/code&gt;) and specify the same IP address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdriesdeboosere.dev%2Fblog%2Ffiles%2Fhow-to-redirect-www-to-non-www-with-nginx%2Fhow-to-redirect-www-to-non-www-with-nginx-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdriesdeboosere.dev%2Fblog%2Ffiles%2Fhow-to-redirect-www-to-non-www-with-nginx%2Fhow-to-redirect-www-to-non-www-with-nginx-01.png" alt="Dns records"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now your servers is accessible by the www and non-www domain, but we still need to configure the redirect. That's the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Nginx redirect
&lt;/h2&gt;

&lt;p&gt;We can do two redirects, a 301 or a 302 redirect. Learn about the difference between the two.&lt;/p&gt;

&lt;p&gt;In our case, we want a permanent 301 redirect, so that all traffic through &lt;a href="http://www.driesdeboosere.dev" rel="noopener noreferrer"&gt;www.driesdeboosere.dev&lt;/a&gt; redirects to driesdeboosere.dev. We'll setup a new Nginx server block that points to your original server block.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login to your server&lt;/li&gt;
&lt;li&gt;Enter following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/nginx/conf.d/redirect.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on which direction you want to redirect, use one of the two options below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: Redirect www to non-www
&lt;/h3&gt;

&lt;p&gt;If you want to redirect your users from www to non-www domain, insert following configuration in the editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    server_name www.driesdeboosere.dev;
    return 301 $scheme://driesdeboosere.dev$request_uri;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit.&lt;/p&gt;

&lt;p&gt;To make the changes take effect, restart Nginx by entering following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test your redirect in the browser; entering &lt;a href="http://www.driesdeboosere.dev" rel="noopener noreferrer"&gt;www.driesdeboosere.dev&lt;/a&gt; will redirect to driesdeboosere.dev.&lt;/p&gt;

&lt;p&gt;We can test this with a curl command, enter following in PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -I www.driesdeboosere.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get a &lt;code&gt;301 Moved Permanently&lt;/code&gt; response like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 12 Aug 2021 13:04:32 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://driesdeboosere.dev/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 2: Redirect non-www to www
&lt;/h3&gt;

&lt;p&gt;If you want to redirect your users from non-www to www domain, insert following configuration in the editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    server_name driesdeboosere.dev;
    return 301 $scheme://www.driesdeboosere.dev$request_uri;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit.&lt;/p&gt;

&lt;p&gt;To make the changes take effect, restart Nginx by entering following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test your redirect in the browser; entering driesdeboosere.dev will redirect to &lt;a href="http://www.driesdeboosere.dev" rel="noopener noreferrer"&gt;www.driesdeboosere.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can test this with a curl command, enter following in PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -I driesdeboosere.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get a &lt;code&gt;301 Moved Permanently&lt;/code&gt; response like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 12 Aug 2021 13:04:32 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://www.driesdeboosere.dev/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That’s it! Your Nginx permanent redirect is now configured properly, and your users will be able to access your web server via your non-www and www domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Difference between a permanent and temporary redirect
&lt;/h2&gt;

&lt;h3&gt;
  
  
  301 redirect (Permanent)
&lt;/h3&gt;

&lt;p&gt;A 301 redirect is an permanent redirect. This way we inform search engines and browsers that a page is permanent redirected to a new address. The old address will be removed from the search engines and be replaced by the new address.&lt;/p&gt;

&lt;h3&gt;
  
  
  302 redirect (Temporary)
&lt;/h3&gt;

&lt;p&gt;A 302 redirect is an temporary redirect. This way we inform search engines and browsers that a page is temporary redirected to a new address.&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>How to add cookie consent in ASP.NET Core 5.0</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Wed, 11 Aug 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-add-cookie-consent-in-asp-net-core-5-0-3d7i</link>
      <guid>https://dev.to/drieze/how-to-add-cookie-consent-in-asp-net-core-5-0-3d7i</guid>
      <description>&lt;p&gt;Learn how to add a cookie consent in an existing ASP.NET Core 3.1 or 5.0 web application.&lt;/p&gt;

&lt;p&gt;Let's configure our &lt;code&gt;Startup.cs&lt;/code&gt; class by add this configuration and using statement.&lt;/p&gt;

&lt;p&gt;Add the using statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add following code in the &lt;code&gt;ConfigureServices&lt;/code&gt; method of your &lt;code&gt;Startup&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sets the display of the Cookie Consent banner (/Pages/Shared/_CookieConsentPartial.cshtml).&lt;/span&gt;
&lt;span class="c1"&gt;// This lambda determines whether user consent for non-essential cookies is needed for a given request.&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CookiePolicyOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CheckConsentNeeded&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MinimumSameSitePolicy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SameSiteMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Strict&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add following code in the &lt;code&gt;Configure&lt;/code&gt; method of your &lt;code&gt;Startup&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseCookiePolicy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Sets the display of the Cookie Consent banner (/Pages/Shared/_CookieConsentPartial.cshtml).&lt;/span&gt;
    &lt;span class="c1"&gt;// This lambda determines whether user consent for non-essential cookies is needed for a given request.&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CookiePolicyOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CheckConsentNeeded&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MinimumSameSitePolicy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SameSiteMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Strict&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRouting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LowercaseUrls&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRazorPages&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;AddRazorRuntimeCompilation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHttpContextAccessor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IProjectService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ProjectService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IBlogService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlogService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IWebHostEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseExceptionHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHsts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseCookiePolicy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseStaticFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRouting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseEndpoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoints&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapRazorPages&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a new Razor page in the &lt;code&gt;Shared&lt;/code&gt; folder with the name: '_CookieConsentPartial.cshtml' and add following code in this new page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@using&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Features&lt;/span&gt;

&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;consentFeature&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ITrackingConsentFeature&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;showBanner&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;consentFeature&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;CanTrack&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cookieString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consentFeature&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;CreateConsentCookie&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;@if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;showBanner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cookieConsent"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="err"&gt;="&lt;/span&gt;&lt;span class="nc"&gt;alert&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dismissible&lt;/span&gt; &lt;span class="n"&gt;fade&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="s"&gt;" role="&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;
&lt;/span&gt;        &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;summarize&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;privacy&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;cookie&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;asp&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/Privacy"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Learn&lt;/span&gt; &lt;span class="n"&gt;More&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="err"&gt;="&lt;/span&gt;&lt;span class="nc"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="s"&gt;" data-dismiss="&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="s"&gt;" aria-label="&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="s"&gt;" data-cookie-string="&lt;/span&gt;&lt;span class="n"&gt;@cookieString&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;aria&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#cookieConsent button[data-cookie-string]"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"click"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cookie&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cookieString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cookieContainer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#cookieConsent"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;cookieContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;})();&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now add the &lt;code&gt;partial&lt;/code&gt; tag-helper in your '_Layout.cshtml' page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pb-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;@RenderBody()&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;partial&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"_CookieConsentPartial"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can place this partial tag-helper anywhere you want in your HTML code.&lt;/p&gt;

&lt;p&gt;If you run your web application you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lwclR7V_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-cookie-consent-in-aspnet-core-50/how-to-add-cookie-consent-in-aspnet-core-50-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lwclR7V_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-cookie-consent-in-aspnet-core-50/how-to-add-cookie-consent-in-aspnet-core-50-01.png" alt="cookie consent example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click &lt;strong&gt;Accept&lt;/strong&gt; then you'll see the cookie message disappear. Refresh your page and you'll see that the message doesn't come back.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>How to add a Spotify playlist to your site</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Wed, 04 Aug 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-add-a-spotify-playlist-to-your-site-10nn</link>
      <guid>https://dev.to/drieze/how-to-add-a-spotify-playlist-to-your-site-10nn</guid>
      <description>&lt;p&gt;Adding a Spotify playlist to your website is realy easy. It's just getting some HTML code from Spotify that you can paste in your own HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Spotify
&lt;/h2&gt;

&lt;p&gt;Open the Spotify application and go to your playlist that you want to share on your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get the HTML
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click on the three dots&lt;/li&gt;
&lt;li&gt;Go to &lt;em&gt;Share&lt;/em&gt; and then &lt;em&gt;Embed playlist&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--auVvDS5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-a-spotify-playlist-to-your-website/how-to-add-a-spotify-playlist-to-your-website-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--auVvDS5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-a-spotify-playlist-to-your-website/how-to-add-a-spotify-playlist-to-your-website-01.png" alt="Embed playlist"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you see the following screen: &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EyBwR6-_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-a-spotify-playlist-to-your-website/how-to-add-a-spotify-playlist-to-your-website-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EyBwR6-_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-a-spotify-playlist-to-your-website/how-to-add-a-spotify-playlist-to-your-website-02.png" alt="Embed playlist"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how your playlist is gonna look like when you paste the html code in your website.&lt;/p&gt;

&lt;p&gt;Now click on the &lt;strong&gt;Copy&lt;/strong&gt; button to copy the code. This should look like something to this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;iframe src="https://open.spotify.com/embed/playlist/5aXXutTCAQMAXHV7juYBR0" width="100%" height="380" frameBorder="0" allowtransparency="true" allow="encrypted-media"&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you paste this HTML code in your the HTML of your website then you'll see the (playable) Spotify playlist on your website. It will look exactly like the playlist you see in the preview:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EyBwR6-_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-a-spotify-playlist-to-your-website/how-to-add-a-spotify-playlist-to-your-website-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EyBwR6-_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-add-a-spotify-playlist-to-your-website/how-to-add-a-spotify-playlist-to-your-website-02.png" alt="Embed playlist"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>websites</category>
      <category>spotify</category>
    </item>
    <item>
      <title>Entity Framework Core Spotify data seed generator</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Mon, 11 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/entity-framework-core-spotify-data-seed-generator-5335</link>
      <guid>https://dev.to/drieze/entity-framework-core-spotify-data-seed-generator-5335</guid>
      <description>&lt;p&gt;For my lecture on ASP.NET Web API I needed some seed data for Entity Framework Core for the API with some relational data.&lt;/p&gt;

&lt;p&gt;I was tired of creating this manually. Yes you have sites that can create dummy data for you but I really needed some relational data between my entities. I needed following relationships between my entities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One to many&lt;/li&gt;
&lt;li&gt;Many to many&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I thought it would be nice if I could do this with some data from &lt;a href="https://www.spotify.com/"&gt;Spotify&lt;/a&gt;. So I began to write my own Spotify scraper to create my seed data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Created entities
&lt;/h2&gt;

&lt;p&gt;With my tool I create several classes with their own properties. The entities are created as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An artist can have many albums&lt;/li&gt;
&lt;li&gt;An artist can have many genres&lt;/li&gt;
&lt;li&gt;An album can have one artist&lt;/li&gt;
&lt;li&gt;An album can have many tracks&lt;/li&gt;
&lt;li&gt;An track can have one album&lt;/li&gt;
&lt;li&gt;An genre can have many artists&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Database scheme
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J9JPzAeu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J9JPzAeu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-13.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Abstract base class
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;

public abstract class EntityBase
{
    public Guid Id { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Properties
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Id&lt;/strong&gt; : the Id for the primary key in your database&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Artist class
&lt;/h3&gt;

&lt;p&gt;An Artist class that derives from the abstract EntityBase class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;

public class Artist : EntityBase
{
    public string Name { get; set; }
    public int Followers { get; set; }
    public int Popularity { get; set; }
    public IEnumerable ArtistGenres { get; set; }
    public IEnumerable Albums { get; set; }
    public string SpotifyId { get; set; }
    public Uri Image { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Properties
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt; : The name of the Artist in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Followers&lt;/strong&gt; : the number of followers in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Popularity&lt;/strong&gt; : the number of popularity in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ArtistGenres&lt;/strong&gt; : a many-to-many class for the genres of the artist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Albums&lt;/strong&gt; : a collections of the albums from the artist in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SpotifyId&lt;/strong&gt; : the artist id in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt; : an Uri with the main image of the artist in Spotify&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Album class
&lt;/h3&gt;

&lt;p&gt;An Album class that derives from the abstract EntityBase class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;

public class Album : EntityBase
{
    public string Name { get; set; }
    public DateTime ReleaseDate { get; set; }
    public int TotalTracks { get; set; }
    public string SpotifyId { get; set; }
    public Uri Image { get; set; }
    public Guid ArtistId { get; set; }
    public Artist Artist { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Properties
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt; : The name of the Album of an artist in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ReleaseDate&lt;/strong&gt; : the release date of the album know by Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TotalTracks&lt;/strong&gt; : the number of tracks of the album in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SpotifyId&lt;/strong&gt; : the album id in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt; : an Uri with the main image of the album in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ArtistId&lt;/strong&gt; : the foreign key to the artist of the album&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artist&lt;/strong&gt; : a navigation property to the Artist of the album&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Track class
&lt;/h3&gt;

&lt;p&gt;An Track class that derives from the abstract EntityBase class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;

public class Track : EntityBase
{
    public string Name { get; set; }
    public string SpotifyId { get; set; }
    public int TrackNumber { get; set; }
    public int DiscNumber { get; set; }
    public int DurationMs { get; set; }
    public bool Explicit { get; set; }
    public Uri PreviewUrl { get; set; }
    public Guid AlbumId { get; set; }
    public Album Album { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Properties
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt; : The name of the Track of an album in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SpotifyId&lt;/strong&gt; : the track id in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TrackNumber&lt;/strong&gt; : the track number of the album know by Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DiscNumber&lt;/strong&gt; : the disc number of the album know by Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DurationMs&lt;/strong&gt; : the duration of a song in milliseconds in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit&lt;/strong&gt; : an Boolean if the track is marked explicit or not in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PreviewUrl&lt;/strong&gt; : an Uri to listen to a preview of the track&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AlbumId&lt;/strong&gt; : a primary key to the album that the track belongs to&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Album&lt;/strong&gt; : a navigation property to the Album of the track&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Genre class
&lt;/h3&gt;

&lt;p&gt;An Genre class that derives from the abstract EntityBase class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;

public class Genre : EntityBase
{
    public string Name { get; set; }
    public IEnumerable ArtistGenres { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Properties
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt; : The name of the Genre in Spotify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ArtistGenres&lt;/strong&gt; : the many to many navigation property to the Artists with this genre&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ArtistGenre class
&lt;/h3&gt;

&lt;p&gt;An ArtistGenre class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;

public class ArtistGenre
{
    public Guid ArtistId { get; set; }
    public Guid GenreId { get; set; }
    public Artist Artist { get; set; }
    public Genre Genre { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Properties
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ArtistId&lt;/strong&gt; : The PK and FK of the ArtistId&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GenreId&lt;/strong&gt; : The PK and FK of the GenreId&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artist&lt;/strong&gt; : The navigation property of the Artist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Genre&lt;/strong&gt; : The navigation property of the Genre&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Created seeding
&lt;/h2&gt;

&lt;p&gt;The tool will create several files for your seeding.&lt;/p&gt;

&lt;h3&gt;
  
  
  DbContext class
&lt;/h3&gt;

&lt;p&gt;An DbContext class with the name you have chosen in the tool. In this example is the name ApplicationDbContext.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using Namespace.Of.Your.Entities;

public class ApplicationDbContext : DbContext
{
    public DbSet Artists { get; set; }
    public DbSet Genres { get; set; }
    public DbSet Albums { get; set; }
    public DbSet Tracks { get; set; }
    public DbSet ArtistGenres { get; set; }

    public ApplicationDbContext(DbContextOptions options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .ToTable("ArtistGenre")
            .HasKey(ag =&amp;gt; new { ag.ArtistId, ag.GenreId }); 
        modelBuilder.Entity()
            .HasOne(ag =&amp;gt; ag.Artist)
            .WithMany(g =&amp;gt; g.ArtistGenres)
            .HasForeignKey(ag =&amp;gt; ag.ArtistId); 
        modelBuilder.Entity()
            .HasOne(ag =&amp;gt; ag.Genre)
            .WithMany(a =&amp;gt; a.ArtistGenres)
            .HasForeignKey(ag =&amp;gt; ag.GenreId); 
        ArtistSeeder.Seed(modelBuilder);
        GenreSeeder.Seed(modelBuilder);
        AlbumSeeder.Seed(modelBuilder);
        TrackSeeder.Seed(modelBuilder);
        ArtistGenreSeeder.Seed(modelBuilder);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Seeder classes
&lt;/h3&gt;

&lt;p&gt;The tool will create five Seeder classes for the Artist, Genre, Track, Album and ArtistGenres seeding. Let's take a look to some the files.&lt;/p&gt;

&lt;h4&gt;
  
  
  ArtistSeeder
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Your.Entities.Namespace.Here;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;

public class ArtistSeeder
{
    public static void Seed(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity().HasData(
            new Artist { Name = "Volbeat", Followers = 1733170, Popularity = 73, SpotifyId = "0L5fC7Ogm2YwgqVCRcF1bT", Image = new Uri("https://i.scdn.co/image/781539dcbee7f7d0186070c75957a0acd35dd7b9"), Id = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), },
            new Artist { Name = "Metallica", Followers = 16357199, Popularity = 84, SpotifyId = "2ye2Wgw4gimLv2eAKyk1NB", Image = new Uri("https://i.scdn.co/image/5a06711d7fc48d5e0e3f9a3274ffed3f0af1bd91"), Id = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), },
            new Artist { Name = "Queens of the Stone Age", Followers = 2524997, Popularity = 72, SpotifyId = "4pejUc4iciQfgdX6OKulQn", Image = new Uri("https://i.scdn.co/image/905233ed063a6350613c571e8508b65c3ae98080"), Id = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), }
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  AlbumSeeder
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Your.Entities.Namespace.Here;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;

public class AlbumSeeder
{

    public static void Seed(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity().HasData(
            new Album { Name = "Rewind, Replay, Rebound (Live in Deutschland)", ReleaseDate = DateTime.Parse("27/11/2020 0:00:00"), TotalTracks = 27, SpotifyId = "0YmDs7WoVGrVevnmWZMA73", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738657a974616cca0510bf6d44"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("84485291-9246-44f8-ae8f-464b8eb8d214"), },
            new Album { Name = "Rewind, Replay, Rebound", ReleaseDate = DateTime.Parse("28/08/2019 0:00:00"), TotalTracks = 14, SpotifyId = "2wX5DsKkNi7yAX6tJPKh8b", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273624e2f2f108b7ce60d818693"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("7c53e1b5-d45e-4f59-975e-e8979e90f6d1"), },
            new Album { Name = "Rewind, Replay, Rebound (Deluxe)", ReleaseDate = DateTime.Parse("2/08/2019 0:00:00"), TotalTracks = 22, SpotifyId = "700dWAqcIsUkNJ1WN1XPT5", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2733664886bf7903ba384ec22d4"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("2549afc5-ce9a-4f9a-bb03-103d06afd1d9"), },
            new Album { Name = "Let's Boogie! (Live from Telia Parken)", ReleaseDate = DateTime.Parse("14/12/2018 0:00:00"), TotalTracks = 26, SpotifyId = "7MD30fGABWb74T0kKLUeTt", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273135a3f9a95ad400499d07164"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("14f9f078-1cae-4d11-bbd8-b63c0ff52af1"), },
            new Album { Name = "Seal The Deal &amp;amp; Let's Boogie (Deluxe)", ReleaseDate = DateTime.Parse("5/08/2016 0:00:00"), TotalTracks = 17, SpotifyId = "6h302sabU6hS5O9WWikjMS", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27356a30f800f0c513effd69593"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("1d7e85b8-8fad-48e2-83b1-c6446d3afa56"), },
            new Album { Name = "Seal The Deal &amp;amp; Let's Boogie", ReleaseDate = DateTime.Parse("3/06/2016 0:00:00"), TotalTracks = 17, SpotifyId = "7l1llpBs2eFfqY4MdYKuh5", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273d8b1d91e505b6d90c9f77de0"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("7d84ad3c-dadf-4027-bcf6-370ad9c25359"), },
            new Album { Name = "Outlaw Gentlemen &amp;amp; Shady Ladies (Deluxe Version)", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 21, SpotifyId = "2As7Yojemyny2lQhClYb7l", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b02528d256d89a06ea1cbf53"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("0c41e044-55ba-4c49-af23-1a07a9bf4326"), },
            new Album { Name = "Outlaw Gentlemen &amp;amp; Shady Ladies", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 14, SpotifyId = "5SBrIIYCvThaqN9r1SV2pv", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27357e78d8652bc2c54332888b7"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("be2271ec-fd7a-44cd-a7a8-18968c03ef82"), },
            new Album { Name = "Beyond Hell / Above Heaven", ReleaseDate = DateTime.Parse("1/01/2012 0:00:00"), TotalTracks = 15, SpotifyId = "2sw5C70KEQdir9M85mDvYP", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273c620bb589e16dff107e49e03"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("538323e4-0602-4af5-8639-77b3a1349fa6"), },
            new Album { Name = "Live From Beyond Hell / Above Heaven", ReleaseDate = DateTime.Parse("1/01/2011 0:00:00"), TotalTracks = 18, SpotifyId = "4zkQxrL6OSwXg314FlMz8z", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27390a8dcb3f3f5a8e58cb8219f"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("4a8b7fb3-f151-4288-9627-20c358a14107"), },
            new Album { Name = "Guitar Gangsters &amp;amp; Cadillac Blood", ReleaseDate = DateTime.Parse("1/01/2008 0:00:00"), TotalTracks = 14, SpotifyId = "6QHLhOasL7wk8EduGT7iD8", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2739daf215ff64034b5f9e02593"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("87283e25-3e2d-4e84-983c-3c1aaaaed6d4"), },
            new Album { Name = "Rock The Rebel / Metal The Devil", ReleaseDate = DateTime.Parse("1/01/2007 0:00:00"), TotalTracks = 11, SpotifyId = "6h0IgkicJholk20m5BtTtU", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737009a136cdbba01e820c6244"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("16815483-1ac0-4ed0-94dc-6cc4c7025e24"), },
            new Album { Name = "The Strength / The Sound / The Songs", ReleaseDate = DateTime.Parse("22/04/2005 0:00:00"), TotalTracks = 15, SpotifyId = "3QA7oan9EaEIlXbfBdbck8", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273c33089161b2c38aeac84567b"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("79d56c13-ddd5-45c9-acdc-d0d3cd0a4a27"), },
            new Album { Name = "S&amp;amp;M2", ReleaseDate = DateTime.Parse("28/08/2020 0:00:00"), TotalTracks = 22, SpotifyId = "7Hc3m7konwS0ugyN8vJhNg", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2731cc6d15e607e0a514b7f4b95"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("eae1b242-61d2-47a8-a46f-638c674ca8a5"), },
            new Album { Name = "Live In Brazil (1993 – 2017)", ReleaseDate = DateTime.Parse("21/04/2020 0:00:00"), TotalTracks = 18, SpotifyId = "2zhgGiT3sNBK2rbrC7JcRW", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27395958b5d219f1b328f083e08"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a4767809-47ec-4776-9a7e-69d1278f7556"), },
            new Album { Name = "Live In Argentina (1993 – 2017)", ReleaseDate = DateTime.Parse("18/04/2020 0:00:00"), TotalTracks = 18, SpotifyId = "5g3oqy7nAK03ke2cR5c95I", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2734d9b5b218dda1a963d06ee45"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("f215c77a-3ba3-46d2-a5b8-e60e2c188737"), },
            new Album { Name = "Live In Chile (1993 – 2017)", ReleaseDate = DateTime.Parse("15/04/2020 0:00:00"), TotalTracks = 18, SpotifyId = "3inFkZMAUrTnPFVSoLHb9O", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273744a08fd20f6bb5c3ffef7c5"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("635b8559-7bc0-469c-a098-8c95edffd109"), },
            new Album { Name = "Helping Hands…Live &amp;amp; Acoustic At The Masonic", ReleaseDate = DateTime.Parse("1/02/2019 0:00:00"), TotalTracks = 12, SpotifyId = "5tEW32iyrRuYPQQ4bwUiCf", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b4763ffbf540cd0c69bbee33"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("f17f1919-3820-436e-b3ea-e3ab90d094f6"), },
            new Album { Name = "Helping Hands...Live &amp;amp; Acoustic at The Masonic", ReleaseDate = DateTime.Parse("1/02/2019 0:00:00"), TotalTracks = 12, SpotifyId = "3KESkLVC8ivaWmZAoDinoc", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732861274cf2dca79cb53334b6"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("cda81d17-2cb6-4cc2-9233-504cb2a49480"), },
            new Album { Name = "ライヴ・イン・テキサス1989 (Live at リユニオン・アリーナ、ダラス、1989)", ReleaseDate = DateTime.Parse("6/04/2017 0:00:00"), TotalTracks = 19, SpotifyId = "0CVEbITaSHVBJO2GnawOaj", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b9f88a8c32bbbb80f15952b4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("ec44f6ff-4d05-4449-86ea-4e547ef810bf"), },
            new Album { Name = "Hardwired…To Self-Destruct (Deluxe)", ReleaseDate = DateTime.Parse("18/11/2016 0:00:00"), TotalTracks = 26, SpotifyId = "4bcUiX49wpmDRhrC8TvDWV", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273e5a07037750e97dca575c690"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("d900c9f9-d204-4f04-abb0-48a24120ba33"), },
            new Album { Name = "Hardwired…To Self-Destruct", ReleaseDate = DateTime.Parse("18/11/2016 0:00:00"), TotalTracks = 12, SpotifyId = "7LwifLL1anaEd9eIIfIkx7", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737b10c20f959932a6c790c074"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a0e3b7cc-dd05-47d3-8e79-f1361b740d01"), },
            new Album { Name = "Metallica Through The Never (Music From The Motion Picture)", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 16, SpotifyId = "0ecPxTAKqXdr2MJYdYOM7e", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2736c5fb059a07c1b2b15a90280"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3b78e1b6-e634-47a9-85da-2c99dfd979e5"), },
            new Album { Name = "Metallica Through The Never (Music from the Motion Picture)", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 16, SpotifyId = "72grIwGP38Iy2S1jxt1Gjd", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273f1a501610a71d48c526c7ecd"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3e529f44-fc67-4c2f-83e1-7caf8b11651b"), },
            new Album { Name = "Lulu", ReleaseDate = DateTime.Parse("1/11/2011 0:00:00"), TotalTracks = 10, SpotifyId = "3FgLMfp5o2h2rAny7S6h57", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273bf3f45395f620f8bbf98d919"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("82e4c858-4320-4964-8f79-4369ec64e65d"), },
            new Album { Name = "Six Feet Down Under", ReleaseDate = DateTime.Parse("1/01/2010 0:00:00"), TotalTracks = 8, SpotifyId = "6PZnDE9gWetRTjw3pHbodW", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738b7be23eb07a8c5c73ef6cfa"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("d8f1fb5a-54c3-4501-94cc-756fffc83598"), },
            new Album { Name = "Six Feet Down Under Part 2", ReleaseDate = DateTime.Parse("1/01/2010 0:00:00"), TotalTracks = 8, SpotifyId = "0kWBvUy985muQ5E0eCGAzH", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273d19ace61eec9f6591a1c4ef2"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("21208ebd-977b-4d95-9056-31c390224d11"), },
            new Album { Name = "Death Magnetic", ReleaseDate = DateTime.Parse("12/09/2008 0:00:00"), TotalTracks = 10, SpotifyId = "0lf5ceMub7KQhLfGxCdM06", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273dfe44d577f07e08564ec73ed"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("5627a1f4-65fb-46e8-ae80-b334c5d59c18"), },
            new Album { Name = "Some Kind Of Monster", ReleaseDate = DateTime.Parse("13/07/2004 0:00:00"), TotalTracks = 8, SpotifyId = "4t0oscNTGJkXiIB2uqZYWg", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2735aa399ec78711c8e2fc42048"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("5626c26d-7ae6-44fb-85e5-e52186330dc4"), },
            new Album { Name = "Some Kind Of Monster (Live)", ReleaseDate = DateTime.Parse("13/07/2004 0:00:00"), TotalTracks = 8, SpotifyId = "3A0FTyAAcjgfhPibPsuVSc", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27396134a0376892706d87910c4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3b7b7ec3-1920-446b-9061-ca955490a387"), },
            new Album { Name = "St. Anger", ReleaseDate = DateTime.Parse("5/06/2003 0:00:00"), TotalTracks = 11, SpotifyId = "4ljK2LVKvEPd5xPgUJn0Bs", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732fe08610316f3e5ebaa06d68"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("0cd651e2-b1fd-4bf2-ba57-803954204ee6"), },
            new Album { Name = "S&amp;amp;M", ReleaseDate = DateTime.Parse("23/11/1999 0:00:00"), TotalTracks = 21, SpotifyId = "3kVRcb2fuCcKcqltzczxRP", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2736b275d72474c508ce2b405a4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("4b57b8e6-2164-4ad6-ba04-051250f643e0"), },
            new Album { Name = "Garage, Inc.", ReleaseDate = DateTime.Parse("24/11/1998 0:00:00"), TotalTracks = 27, SpotifyId = "5b7HQ04lPT7eGJQ7fmVsjC", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737e1f85f69323acac962516c4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("032320d1-1112-47e7-968e-3b2a926fa58a"), },
            new Album { Name = "Garage Inc.", ReleaseDate = DateTime.Parse("1/01/1998 0:00:00"), TotalTracks = 27, SpotifyId = "0vshXZYhBkbIoqxyC2fXcF", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27375e6375e11550746705a9645"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("571d4078-a850-4d63-af49-1bce94ccbef2"), },
            new Album { Name = "Reload", ReleaseDate = DateTime.Parse("18/11/1997 0:00:00"), TotalTracks = 13, SpotifyId = "7KDqRmr937ylvGilPGWxfD", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273a49eff6d64cafc2551553380"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3028af10-55f7-4d08-b0bc-367cc0834217"), },
            new Album { Name = "Load", ReleaseDate = DateTime.Parse("4/06/1996 0:00:00"), TotalTracks = 14, SpotifyId = "5rI3pfrpvmdYtGAsBwaGec", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2730a3eb7ef6df5732fc6fa77ec"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("7963cf47-4fa8-4845-9e4f-f7d58a48c921"), },
            new Album { Name = "Live S**t: Binge &amp;amp; Purge", ReleaseDate = DateTime.Parse("23/11/1993 0:00:00"), TotalTracks = 24, SpotifyId = "4iBN00FZaKlaXVYfxV7bBQ", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273c99dbd20668c97579417595f"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("34c175ea-f21f-4e44-bf26-ad98b7fded7a"), },
            new Album { Name = "Live Sh*t: Binge &amp;amp; Purge (Live In Mexico City)", ReleaseDate = DateTime.Parse("1/01/1993 0:00:00"), TotalTracks = 24, SpotifyId = "6TXWP5SAhTB9P0GN4tOT0B", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273f003fc67301640e0e99a77eb"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("1cba7915-f3d2-4ff9-98a5-1fa6970034b6"), },
            new Album { Name = "Metallica", ReleaseDate = DateTime.Parse("12/08/1991 0:00:00"), TotalTracks = 12, SpotifyId = "2Kh43m04B1UkVcpcRa1Zug", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273cf84c5b276431b473e924802"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("cd5ab0de-a75b-4d33-a3fc-02f18f2eabca"), },
            new Album { Name = "...And Justice for All (Remastered)", ReleaseDate = DateTime.Parse("7/09/1988 0:00:00"), TotalTracks = 9, SpotifyId = "4Cn4T0onWhfJZwWVzU5a2t", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738161357a12a172721e772e0d"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("89c42f56-bd2c-4c25-a33e-c7629b3201e7"), },
            new Album { Name = "...And Justice for All (Remastered Deluxe Box Set)", ReleaseDate = DateTime.Parse("7/09/1988 0:00:00"), TotalTracks = 147, SpotifyId = "2XbWaerVk9fjhEiGSrd6TF", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273be54746b374358970b5e617a"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("32873e8b-b913-4d66-9190-f023e29756b5"), },
            new Album { Name = "…And Justice for All (Remastered)", ReleaseDate = DateTime.Parse("25/08/1988 0:00:00"), TotalTracks = 9, SpotifyId = "6jZ1z25PyF4Yd3kHxt9rl1", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273fe896727e3db1027ed72d885"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("04cc98ef-a9c0-475f-b529-e3477a87fd62"), },
            new Album { Name = "...And Justice For All", ReleaseDate = DateTime.Parse("25/08/1988 0:00:00"), TotalTracks = 9, SpotifyId = "6Eycw3dwcDMEFSqkUvLQ7g", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737c05e69390ab7c628a83cee7"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("0bd48e82-f3b2-4909-8124-aaeffbec8d69"), },
            new Album { Name = "…And Justice for All (Remastered Deluxe Box Set)", ReleaseDate = DateTime.Parse("25/08/1988 0:00:00"), TotalTracks = 147, SpotifyId = "2bKDte0I4SceROjBMtYtKV", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2734c9fc157cd0b0ce4196f9aeb"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("fa3b3a48-e692-47af-a3c4-02d9b3dec9fa"), },
            new Album { Name = "Master Of Puppets (Deluxe Box Set / Remastered)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 137, SpotifyId = "5rFZcoCvmCaJ1gxTMU4JTm", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27316d6f039fafd389911261ada"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("fc834878-f512-4fb8-ab5f-a76b5665767b"), },
            new Album { Name = "Master of Puppets (Remastered Deluxe Box Set)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 137, SpotifyId = "7CGhx630DIjdJqaBDVKc5j", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273cad4832cb7b5844343278daa"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a5a4b71a-eb08-4448-bc9c-25e71455ab90"), },
            new Album { Name = "Master Of Puppets (Remastered)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 8, SpotifyId = "2Lq2qX3hYhiuPckC8Flj21", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273668e3aca3167e6e569a9aa20"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("8a15aee2-84ac-4b25-bf0a-8a133dbf6cd1"), },
            new Album { Name = "Master of Puppets (Remastered)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 8, SpotifyId = "5gzLOflH95LkKYE6XSXE9k", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732127e0afac383fb73d533a7d"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("2725fbb3-5362-44b1-a245-ddb99a8480da"), },
            new Album { Name = "Ride The Lightning (Deluxe Remaster)", ReleaseDate = DateTime.Parse("27/07/1984 0:00:00"), TotalTracks = 63, SpotifyId = "2omIeSJEGQeKHPOpiXgfkr", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273533fd0b248052d04e6b732c0"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("006032e0-8b56-4876-bad8-672da756ccd0"), },
            new Album { Name = "Ride The Lightning (Remastered)", ReleaseDate = DateTime.Parse("27/07/1984 0:00:00"), TotalTracks = 8, SpotifyId = "1nTvIQEXvygqSIqc2vuwAz", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b09e5084136821bf64d327f4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("fcebeaa9-e555-4a64-82cb-f18561e14d39"), },
            new Album { Name = "Ride The Lightning (Deluxe / Remastered)", ReleaseDate = DateTime.Parse("26/07/1984 0:00:00"), TotalTracks = 64, SpotifyId = "4K5E5mWQbECn9aThu6Xnkx", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27396a926d07aea417327ea024a"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("cd4acc8b-6bc2-4c56-b5f6-c01ad099cfe5"), },
            new Album { Name = "Kill 'Em All (Deluxe Remaster)", ReleaseDate = DateTime.Parse("25/07/1983 0:00:00"), TotalTracks = 54, SpotifyId = "7GttoSWxEi5lZvIWeSrh6n", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273a4c3675649cce210651d150d"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("d83fdf25-a430-4e31-a82a-06059cb43218"), },
            new Album { Name = "Kill 'Em All (Remastered)", ReleaseDate = DateTime.Parse("25/07/1983 0:00:00"), TotalTracks = 10, SpotifyId = "0vNBQof86Lv5gLuf26ML7o", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27320292e6cce666a69ba5a86fb"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("0fd27ec2-bafc-4153-87fb-d207a24f7548"), },
            new Album { Name = "Kill 'Em All (Deluxe / Remastered)", ReleaseDate = DateTime.Parse("24/07/1983 0:00:00"), TotalTracks = 58, SpotifyId = "3m69LQokz6DaKB3yw4BH6n", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732875b8b37127cc23f6915c77"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a7801b99-8cda-4a30-856b-d1a08fe2a84b"), },
            new Album { Name = "Villains", ReleaseDate = DateTime.Parse("25/08/2017 0:00:00"), TotalTracks = 9, SpotifyId = "7vuIN24G18PAUAvjnICyA6", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27326e26899d11b39b400e5252c"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("4fb73071-3478-408a-a72d-5c481e53ddf1"), },
            new Album { Name = "...Like Clockwork", ReleaseDate = DateTime.Parse("3/06/2013 0:00:00"), TotalTracks = 10, SpotifyId = "5T5NM01392dvvd4EhGrCnj", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273eee7c041844e45dd76469fa0"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("2d86048a-1a1f-468d-afcf-2180aae905e3"), },
            new Album { Name = "Rated R - Deluxe Edition", ReleaseDate = DateTime.Parse("1/01/2010 0:00:00"), TotalTracks = 26, SpotifyId = "10UBEkRjqtl0iT2BRAwcto", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2730fa7b83a64a2501b6de8db39"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("c00460f8-0373-43a8-b626-2d8cba290569"), },
            new Album { Name = "Era Vulgaris", ReleaseDate = DateTime.Parse("1/01/2007 0:00:00"), TotalTracks = 15, SpotifyId = "1w71aBHYJ1zTOsSsmr2Fca", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27301b7dc44ae31364925b4eadc"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("89ff74e2-3da0-44ee-a3f3-70000d4bb7e3"), },
            new Album { Name = "Era Vulgaris Tour Edition", ReleaseDate = DateTime.Parse("1/01/2007 0:00:00"), TotalTracks = 24, SpotifyId = "2kJqBMlDAgX9HNfCMLlYrS", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738597d5ec11783f4f3a33c314"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("8dea2667-5300-4ebf-b0c1-015d287a8a1e"), },
            new Album { Name = "Over The Years And Through The Woods (Live At Brixton Academy / 2005)", ReleaseDate = DateTime.Parse("22/11/2005 0:00:00"), TotalTracks = 14, SpotifyId = "2vQTLy1EZ9JPaUU68lUMgR", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273214612618a7148d52bf1913a"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("2d1ba5b8-733d-4cb3-a1b7-a00acbf55750"), },
            new Album { Name = "Lullabies To Paralyze", ReleaseDate = DateTime.Parse("1/01/2005 0:00:00"), TotalTracks = 16, SpotifyId = "68ZycIjwlQ0fvtaxVXmgn8", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273ab1aaed1d2f9019183390a98"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("7fe3f405-51e9-4ca4-8383-b5016d446451"), },
            new Album { Name = "Songs For The Deaf", ReleaseDate = DateTime.Parse("1/01/2002 0:00:00"), TotalTracks = 16, SpotifyId = "4w3NeXtywU398NYW4903rY", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2739eec33b045d88f87b9b06e67"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("9a307aaf-95ea-4913-973e-25c4561f9b88"), },
            new Album { Name = "Rated R", ReleaseDate = DateTime.Parse("6/06/2000 0:00:00"), TotalTracks = 12, SpotifyId = "05tJhGl52X4zGe0ySlcBk6", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2739c4d9db5d6895352b6eea6fc"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("5d1b2c31-fdf1-4734-9c1d-bc6aa9d11754"), },
            new Album { Name = "Queens of the Stone Age", ReleaseDate = DateTime.Parse("22/09/1998 0:00:00"), TotalTracks = 14, SpotifyId = "4ZVYZI1wY4TmLOQ3as1UNI", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732021e21bc55e928b744a0113"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("f5354d88-1b06-4724-ab92-1bfb90f52015"), }
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And of course this is the same for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TrackSeeder&lt;/li&gt;
&lt;li&gt;GenreSeeder&lt;/li&gt;
&lt;li&gt;ArtistGenreSeeder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the entities have a foreign key Guid ID that relate to a primary key Guid ID in the seeding.&lt;/p&gt;

&lt;p&gt;You can find my &lt;a href="https://driesdeboosere.dev/tools/spotify-seed-data-generator"&gt;Spotify seed data generator here&lt;/a&gt;. Below you'll find some sort of manual to use my tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spotify seed data generator manual
&lt;/h2&gt;

&lt;p&gt;1. What you'll need&lt;/p&gt;

&lt;p&gt;2. Choose your artists&lt;/p&gt;

&lt;p&gt;3. Get your Spotify OAuth token&lt;/p&gt;

&lt;p&gt;4. Use the Spotify seed data generator tool&lt;/p&gt;

&lt;p&gt;5. Download the files&lt;/p&gt;

&lt;p&gt;6. Copy folders in your project&lt;/p&gt;

&lt;p&gt;7. Configure your connectionstring&lt;/p&gt;

&lt;p&gt;8. Configure your Startup&lt;/p&gt;

&lt;p&gt;9. Add migration&lt;/p&gt;

&lt;p&gt;10. Update database&lt;/p&gt;

&lt;h3&gt;
  
  
  What you'll need
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Spotify premium account (for your Spotify OAuth token)&lt;/li&gt;
&lt;li&gt;ASP.NET Core application (API, MVC, Razor Pages, Blazor, ...)&lt;/li&gt;
&lt;li&gt;Your favorite browser&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choose your artists
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://open.spotify.com/"&gt;Spotify Web player&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Search for your favorite artist by clicking on "Search" or &lt;a href="https://open.spotify.com/search"&gt;click here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Search "&lt;a href="https://open.spotify.com/search/Metallica"&gt;Metallica&lt;/a&gt;" for example:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c6i9P69c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c6i9P69c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-01.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the name of the artist to go to the artist page&lt;/li&gt;
&lt;li&gt;In the address bar of your browser you can now see the &lt;strong&gt;Spotify Artist ID&lt;/strong&gt; of Metallica:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--axStlt-W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--axStlt-W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-02.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy this artist ID and paste it somewhere, we will need this ID later in the tool.&lt;/li&gt;
&lt;li&gt;If you want additional artists, then repeat these steps to retain their Spotify artists ID's.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Get your Spotify OAuth token
&lt;/h3&gt;

&lt;p&gt;Now it's time to get your (temporary) Spotify token. We will get this temporary token from the developer site from Spotify. If you already have a Spotify token, then you can skip this step and use your own token.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://developer.spotify.com/console/get-several-artists/"&gt;this page&lt;/a&gt; to get some random Spotify artists through the Spotify Console for Developers. We won't need the artists but we only go to this page to get the Spotify token in a easy way.&lt;/li&gt;
&lt;li&gt;Click on the green button "GET TOKEN":&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EAMab-uN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EAMab-uN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-03.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login with your Spotify Credentials&lt;/li&gt;
&lt;li&gt;On the next screen you don't need the check any boxes for the scopes, you can click on the green button "REQUEST TOKEN":&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J9mF8YcE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J9mF8YcE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-04.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You'll obtain an OAuth Token key in the textbox like this:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dypau1_P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dypau1_P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-05.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy this token and paste it somewhere, because we'll need this token in the tool to identity yourself to Spotify.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind that this token expires really quick, so maybe you'll have to repeat this steps to get a new "fresh" token from Spotify.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Use the Spotify seed data generator tool
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;a href="https://driesdeboosere.dev/tools/spotify-seed-data-generator"&gt;Spotify seed data generator tool&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Fill in your Spotify OAuth token&lt;/li&gt;
&lt;li&gt;Fill in your Spotify artist id's &lt;strong&gt;(I you have multiple ID's, then separate them by a comma)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose a name for your DbContext class&lt;/li&gt;
&lt;li&gt;Choose a namespace for your DbContext class&lt;/li&gt;
&lt;li&gt;Choose a namespace for your entity classes&lt;/li&gt;
&lt;li&gt;Click on the GO button!&lt;/li&gt;
&lt;li&gt;Wait :-)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XhrhcWyt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XhrhcWyt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-06.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Download the files
&lt;/h3&gt;

&lt;p&gt;After the tool does the scraping throught the Spotify API you can download the zip file that contains all the nessecary files:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fbtVKsBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fbtVKsBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-07.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the zip file you'll find two folders; Data and Entities:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_HMlq2Z8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_HMlq2Z8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-08.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Entities folder contains all the entity classes and a folder that contains the BaseEntity class:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--utpvMPrU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--utpvMPrU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-09.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Data folder contains the DbContext class and the Seeder classes:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UpBrj6SD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UpBrj6SD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-10.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Copy folders in your project
&lt;/h3&gt;

&lt;p&gt;Create a new ASP.NET Core web project and copy the folders where you want them to be. For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bljfU6CJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bljfU6CJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-11.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure your connectionstring
&lt;/h3&gt;

&lt;p&gt;Go to your appsettings.json and add&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "ConnectionStrings": {
    "DefaultDatabase": "Server=(localdb)\\mssqllocaldb;Database=TEST.SpotifySeedGenerator;Trusted_Connection=True;"
  },
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to your appsettings.json. So it would look like this. Of course you can change the database name or choose a different server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "ConnectionStrings": {
    "DefaultDatabase": "Server=(localdb)\\mssqllocaldb;Database=TEST.SpotifySeedGenerator;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure your Startup
&lt;/h3&gt;

&lt;p&gt;Add the following code in the ConfigureServices method from your Startup.cs class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services.AddDbContext(options =&amp;gt;
                options.UseSqlServer(Configuration.GetConnectionString("DefaultDatabase")));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've chosen a different name for your DbContext than you need the change ApplicationDbContext to the name you have chosen.&lt;/p&gt;

&lt;h4&gt;
  
  
  Install NuGet packages
&lt;/h4&gt;

&lt;p&gt;Install the following NuGet packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.Design&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.Relational&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.SqlServer&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.Tools (If you don't have them globally installed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And import the required namespaces in your Startup.cs class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add migration
&lt;/h3&gt;

&lt;p&gt;Open a PowerShell terminal at the root of your project and type in following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ dotnet ef migrations add "InitialCreate"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update database
&lt;/h3&gt;

&lt;p&gt;And to update your database type in following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ dotnet ef database update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open your database server manager of your choice, inspect the tables and you'll see that your tables contain data. In this example I opened the Albums table with the build-in Server Explorer in Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HPMHfxzx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HPMHfxzx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/entity-framework-core-spotify-data-seed-generator/entity-framework-core-spotify-data-seed-generator-12.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to (ab)use and/or share this tool. If you have any problems or suggestions, than ping me at &lt;a href="https://twitter.com/Drieze_"&gt;Twitter&lt;/a&gt;, and I'll see what I can do for you.&lt;/p&gt;

</description>
      <category>tools</category>
      <category>entityframeworkcore</category>
      <category>aspnetcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Lowercase URLs in ASP.NET Core.</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Tue, 25 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/lowercase-urls-in-asp-net-core-597a</link>
      <guid>https://dev.to/drieze/lowercase-urls-in-asp-net-core-597a</guid>
      <description>&lt;p&gt;When you create links in your ASP.NET Core web application with TagHelpers then each word in your URL will start with a capital letter.&lt;/p&gt;

&lt;p&gt;Take this for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;a asp-controller="About" asp-action="Index"&amp;gt;About&amp;lt;/a&amp;gt;
&amp;lt;a asp-controller="Tools" asp-action="Index"&amp;gt;Tools&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will result in following HTML code where each word from the controller and action name starts with a capital letter in the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;a href="https://driesdeboosere.dev/About"&amp;gt;About&amp;lt;/a&amp;gt;
&amp;lt;a href="https://driesdeboosere.dev/Tools"&amp;gt;Tools&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And even in your web browsers address bar the generated URL from the controller and action name starts with a capital letter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T-ghyZ4g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/lowercase-urls-in-asp-net-core/lowercase-urls-in-asp-net-core-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T-ghyZ4g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/lowercase-urls-in-asp-net-core/lowercase-urls-in-asp-net-core-01.png" alt="URL in address bar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would like to have all my URLs in lowercase, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;a href="https://driesdeboosere.dev/about"&amp;gt;About&amp;lt;/a&amp;gt;
&amp;lt;a href="https://driesdeboosere.dev/tools"&amp;gt;Tools&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luckily we can easily set this up in our &lt;strong&gt;Startup.cs&lt;/strong&gt; class in the &lt;strong&gt;ConfigureServices&lt;/strong&gt; method. We just need to setup the route options by adding the AddRouting extension method to services and set the &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.routing.routeoptions.lowercaseurls?view=aspnetcore-3.1"&gt;RouteOptions LowercaseUrls property&lt;/a&gt; to true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services.AddRouting(options =&amp;gt; options.LowercaseUrls = true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Be aware that you put this options BEFORE services.AddMvc() or services.AddControllersWithViews()!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;See this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services)
{
    services.AddRouting(options =&amp;gt; options.LowercaseUrls = true);
    services.AddControllersWithViews().AddRazorRuntimeCompilation();
    // other configurations
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all our URLs created by our TagHelpers will be in lowercase.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>How to exclude own visits (online and development) from Google Analytics</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-exclude-own-visits-online-and-development-from-google-analytics-28m6</link>
      <guid>https://dev.to/drieze/how-to-exclude-own-visits-online-and-development-from-google-analytics-28m6</guid>
      <description>&lt;p&gt;When you use Google Analytics for your web analytics and statistics it can be annoying to get your own visits in the statistics. Especially if you are testing something on your own website.&lt;/p&gt;

&lt;p&gt;I was updating some meta tags on my own live website and while testing them out I didn't want to count my own visits in the Google Analytics data. So I wrote a filter to exclude my own IP address from the data.&lt;/p&gt;

&lt;p&gt;Only downside with this approach is that I need to update my IP address in the filter because my IP address provided from my ISP could change from time to time. I will look into this in the future to see if I can write a script or something to be notified when my IP address changes so I can update the filter in Google Analytics.&lt;/p&gt;

&lt;p&gt;Another possible solution is to exclude the Google Analytics script if your logged in to your website and/or if your developing your website on your localhost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get to know your own IP address
&lt;/h2&gt;

&lt;p&gt;First you will need to know your own IP address. If you don't know how to lookup your own IP address you can visit &lt;a href="https://www.whatismyip.com/"&gt;https://www.whatismyip.com/&lt;/a&gt; and copy your public IPv4 address.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a IP address filter in Google Analytics
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Login to your Google Analytics account&lt;/li&gt;
&lt;li&gt;Click on admin (below on the left)&lt;/li&gt;
&lt;li&gt;Go to the account where you want to create the filter&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;All Filters&lt;/strong&gt; in the &lt;em&gt;ACCOUNT&lt;/em&gt; column&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FsHgrhRW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FsHgrhRW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-01.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the &lt;strong&gt;+ ADD FILTER&lt;/strong&gt; button (If you don't see this button, it means you don't the proper rights to do this)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tAclTIBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tAclTIBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-02.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Give your filter a proper name (Like &lt;em&gt;Exclude my own IP address&lt;/em&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8TPB2f60--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8TPB2f60--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-03.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select the &lt;strong&gt;Predefined&lt;/strong&gt; filter type, select &lt;strong&gt;Exclude&lt;/strong&gt; , &lt;strong&gt;traffic from the IP addresses&lt;/strong&gt; and &lt;strong&gt;that are equal to&lt;/strong&gt;. Enter your IP address in the textbox IP address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9AOU27cB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9AOU27cB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-04.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Move the available views to the &lt;strong&gt;Selected views&lt;/strong&gt; and hit the &lt;strong&gt;Save&lt;/strong&gt; button.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dHdnxZAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dHdnxZAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-exclude-own-visits-from-google-analytics/google-analytics-create-ip-filter-05.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! Now your own visits from your IP address will not appear in the Google Analytics statistics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exclude tracking code if you are logged in to your website
&lt;/h2&gt;

&lt;p&gt;If you are using a website with a authorization system, than you can put some code in your header tag to render the &lt;strong&gt;Global Site Tag (gtag.js)&lt;/strong&gt; if a user is not logged in.&lt;/p&gt;

&lt;p&gt;Pseudo code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
    if(User.IsNotLoggedIn)
    {
        &amp;lt;!-- Global site tag (gtag.js) - Google Analytics --&amp;gt;
        &amp;lt;script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxxxxx-xx"&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script&amp;gt;
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', 'UA-xxxxxxxx-xx');
        &amp;lt;/script&amp;gt;
    }
&amp;lt;/head&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exclude tracking in development
&lt;/h2&gt;

&lt;p&gt;If you are developing and testing new features on your website, than you don't want this traffic neither in your Google Analytics statistics. If your using &lt;a href="https://localhost:5001"&gt;https://localhost:5001&lt;/a&gt; (or other port) for your development than you can check if the URL from your website contains &lt;strong&gt;localhost:&lt;/strong&gt; in the path.&lt;/p&gt;

&lt;p&gt;Pseudo code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
    if(UrlPath.DoesNotContains("localhost:"))
    {
        &amp;lt;!-- Global site tag (gtag.js) - Google Analytics --&amp;gt;
        &amp;lt;script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxxxxx-xx"&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script&amp;gt;
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', 'UA-xxxxxxxx-xx');
        &amp;lt;/script&amp;gt;
    }
&amp;lt;/head&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>googleanalytics</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>How to deploy ASP.NET Core 3.1 app to Digital Ocean Linux droplet</title>
      <dc:creator>Dries Deboosere</dc:creator>
      <pubDate>Mon, 10 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/drieze/how-to-deploy-asp-net-core-3-1-app-to-digital-ocean-linux-droplet-f8o</link>
      <guid>https://dev.to/drieze/how-to-deploy-asp-net-core-3-1-app-to-digital-ocean-linux-droplet-f8o</guid>
      <description>&lt;p&gt;In this tutorial we will deploy and host a simple ASP.NET Core 3.1 demo app on Ubuntu 18.04 droplet in Digital Ocean.&lt;/p&gt;

&lt;p&gt;You can download or clone the demo app from my &lt;a href="https://github.com/Drieze/DriesDeboosere.Dev.Demo"&gt;GitHub&lt;/a&gt;, or you can deploy your own ASP.NET Core 3.1 application. Just keep in my mind that this demo app &lt;strong&gt;doesn't make use of a database&lt;/strong&gt;. So in this tutorial we don't setup a database. Maybe I'll write another tutorial about implementing an MySql server.&lt;/p&gt;

&lt;p&gt;We will break this up in different steps:&lt;/p&gt;

&lt;p&gt;1. Create Digital Ocean Ubuntu droplet&lt;/p&gt;

&lt;p&gt;2. Create a new user in Ubuntu&lt;/p&gt;

&lt;p&gt;&lt;a href="//#install.net-sdk-in-ubuntu"&gt;3. Install .NET SDK in Ubuntu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="//#deploy-our-asp.net-core-3.1-app-to-ubuntu"&gt;4. Deploy our ASP.NET Core 3.1 app to Ubuntu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5. Install and configure NGINX in Ubuntu&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Digital Ocean Ubuntu droplet
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create Digital Ocean account
&lt;/h3&gt;

&lt;p&gt;First of all, you'll need a Digital Ocean account. If you haven't an DO account than you can create an account with this &lt;a href="https://m.do.co/c/1f04571a4bbe"&gt;referral link&lt;/a&gt; and you'll get $100 credits to spend in the next 60 days.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Digital Ocean project
&lt;/h3&gt;

&lt;p&gt;Once you're logged in, create a new project by clicking on the &lt;strong&gt;+ New Project&lt;/strong&gt; link:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--79mmlY9n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--79mmlY9n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-01.png" alt="digital-ocean-create-project 01"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next screen you'll need to enter an name, description and tell DO what want to do with the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Okym1O2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Okym1O2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-02.png" alt="digital ocean create project 02"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you're done, click on the &lt;strong&gt;Create Project&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6RbxRmtW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6RbxRmtW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-03.png" alt="digital ocean create project 03"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next screen click on the &lt;strong&gt;Skip for now&lt;/strong&gt; link below.&lt;/p&gt;

&lt;p&gt;Now it's time to create our droplet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S526fFQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S526fFQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-project-04.png" alt="digital ocean create project 04"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;Get Started with a Droplet&lt;/strong&gt; button&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Digital Ocean droplet
&lt;/h3&gt;

&lt;p&gt;Now it's time to create a droplet! First we have to choose an image distribution, in our case we choose &lt;strong&gt;Ubuntu 18.04.3 (LTS) x64&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NfE8BXjX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NfE8BXjX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-01.png" alt="digital ocean create droplet 01"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We choose the &lt;strong&gt;Basic&lt;/strong&gt; plan for &lt;strong&gt;$5/mo&lt;/strong&gt; (scroll to the left):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i4P2tqOL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i4P2tqOL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-02.png" alt="digital ocean create droplet 02"&gt;&lt;/a&gt; &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CnvaX3s2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CnvaX3s2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-03.png" alt="digital ocean create droplet 03"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We &lt;strong&gt;don't need block storage&lt;/strong&gt; , so we'll skip that.&lt;/p&gt;

&lt;p&gt;Choose a data center region close to your hometown, in my case I'll choose &lt;strong&gt;Amsterdam&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--17ql5evd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--17ql5evd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-04.png" alt="digital ocean create droplet 04"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the authentication, choose SSH Keys and click on the New SSH Key button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MqmiOOc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MqmiOOc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-05.png" alt="digital ocean create droplet 05"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then follow the steps described on the right:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xUfniwco--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xUfniwco--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-06.png" alt="digital ocean create droplet 06"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it's time to finalize and create our droplet. In my case I added &lt;strong&gt;backups&lt;/strong&gt; , but for this demo purposes you don't have to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rLMtOPyY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rLMtOPyY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-07.png" alt="digital ocean create droplet 07"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click on the &lt;strong&gt;Create Droplet&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Now DO will create this droplet (give it some seconds). When everything is done you'll see the droplet and it's IP address. Something like this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5NXtelnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5NXtelnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/digital-ocean-create-droplet-08.png" alt="digital ocean create droplet 07"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you enter the IP address in your browser you'll get an error. This is normal, because we only have a droplet with Ubuntu. But we have to configure our Linux VPS. Let's do this next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a new user in Ubuntu
&lt;/h2&gt;

&lt;p&gt;We need to login into our server. We'll do this through SSH. You can download &lt;a href="https://www.putty.org/"&gt;PUTTY&lt;/a&gt; or download &lt;a href="https://github.com/PowerShell/PowerShell/releases"&gt;PowerShell&lt;/a&gt; (Scroll down to assets to download). In my case I'll use PowerShell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect with SSH to the server
&lt;/h3&gt;

&lt;p&gt;Open PowerShell and SSH into your droplet through this command to log in to your server as the root user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh root@
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The IP address from my droplet is 167.172.37.58. Change the IP address by your droplets IP address&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh root@167.172.37.58
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;strong&gt;yes&lt;/strong&gt; if you get this message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The authenticity of host '167.172.37.58 (167.172.37.58)' can't be established.
ECDSA key fingerprint is SHA256:VodrbvWvtonPzxiFpRiuoq0tTrgZjow+YIGUOXukx7w.
Are you sure you want to continue connecting (yes/no)?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By typing yes the connection closes, so I'll need to login again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh root@167.172.37.58
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you're asked to enter your passphrase. Enter your passphrase (or paste it with the right mouse button) and hit enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter passphrase for key 'C:\Users\dries.deboosere/.ssh/id_rsa':
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we're logged in to the server as the root user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-66-generic x86_64)Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-66-generic x86_64)

 * Documentation: https://help.ubuntu.com
 * Management: https://landscape.canonical.com
 * Support: https://ubuntu.com/advantage

  System information as of Sun Aug 9 15:24:27 UTC 2020

  System load: 0.0 Processes: 81
  Usage of /: 4.0% of 24.06GB Users logged in: 0
  Memory usage: 11% IP address for eth0: 167.172.37.58
  Swap usage: 0%

0 packages can be updated.
0 updates are security updates.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

root@ubuntu-s-1vcpu-1gb-ams3-01:~#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create new user
&lt;/h3&gt;

&lt;p&gt;First we'll create a new user on the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adduser USERNAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A little explanation about these commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;adduser&lt;/strong&gt; : create a new user with the name of USERNAME&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;USERNAME&lt;/strong&gt; : the username for the new user. In my case I'll use _ &lt;strong&gt;dries&lt;/strong&gt; _ as the username&lt;/p&gt;

&lt;p&gt;Now enter following commands in PowerShell with your username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adduser dries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user _ &lt;strong&gt;dries&lt;/strong&gt; _ is now created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@ubuntu-s-1vcpu-1gb-ams3-01:~# adduser dries
Adding user `dries' ...
Adding new group `dries' (1000) ...
Adding new user `dries' (1000) with group `dries' ...
Creating home directory `/home/dries' ...
Copying files from `/etc/skel' ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your asked to choose a password. Enter the password and confirm your password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your asked about some information. You can fill this in or press ENTER for the default values. In my case I press ENTER and at the end I choose yes by typing &lt;strong&gt;y&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Changing the user information for dries
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Give administrator/sudo privileges to our new user
&lt;/h3&gt;

&lt;p&gt;Now our new user needs to get administrator/sudo privileges. So let set this up. To do this we'll need following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usermod -a -G sudo USERNAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A little explanation about these commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;usermod&lt;/strong&gt; : calls the program&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-a&lt;/strong&gt; : to add the user to a group&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-G&lt;/strong&gt; : to specify the group&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sudo&lt;/strong&gt; : stands for &lt;strong&gt;'super user do'&lt;/strong&gt;. This will execute root commands as an non-root user.&lt;/p&gt;

&lt;p&gt;Now enter following commands in PowerShell with your username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usermod -a -G sudo dries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I want the same ssh key for the root user and for the new created user (dries). We can copy this key by following commands (change &lt;strong&gt;dries&lt;/strong&gt; by your username):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp -r ~/.ssh /home/dries/
sudo chown -R dries:dries /home/dries/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now restart the SSH service by following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service ssh restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now exit the server by typing the exit command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's time to login as the new created user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh dries@167.172.37.58
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll be asked for the passphrase. Because we copied over the ssh key from root user to dries we can now use the same passphrase from the root user. Enter the passphrase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter passphrase for key 'C:\Users\dries.deboosere/.ssh/id_rsa':
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should see this in PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dries@ubuntu-s-1vcpu-1gb-ams3-01:~$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means we're now logged in as user &lt;strong&gt;dries&lt;/strong&gt; in the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install .NET SDK in Ubuntu
&lt;/h2&gt;

&lt;p&gt;Now it's time to install .NET on Ubuntu. We can go to the &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#1804-"&gt;Microsoft documentation website&lt;/a&gt; to see which commands we need to install this on our Ubuntu 18.04 server.&lt;/p&gt;

&lt;p&gt;First we install the Microsoft package sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we install the .NET 3.1 SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install -y dotnet-sdk-3.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we check if it's installed by running following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet --info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something similar like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.NET Core SDK (reflecting any global.json):
 Version: 3.1.302
 Commit: 41faccf259

Runtime Environment:
 OS Name: ubuntu
 OS Version: 18.04
 OS Platform: Linux
 RID: ubuntu.18.04-x64
 Base Path: /usr/share/dotnet/sdk/3.1.302/

Host (useful for support):
  Version: 3.1.6
  Commit: 3acd9b0cd1

.NET Core SDKs installed:
  3.1.302 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.App 3.1.6 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.6 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploy our ASP.NET Core 3.1 app to Ubuntu
&lt;/h2&gt;

&lt;p&gt;Now it's finally time to publish our ASP.NET Core app to the server. But first we need to make some arrangements. We'll going to be using the instructions from the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-3.1"&gt;Microsoft documentation&lt;/a&gt; to host our ASP.NET Core app on Linux to deploy our app.&lt;/p&gt;

&lt;p&gt;For this tutorial I'll use a simple demo ASP.NET Core 3.1 web application. You can use your own application or else you can clone/download my demo application from my &lt;a href="https://github.com/Drieze/DriesDeboosere.Dev.Demo"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are many ways to deploy the files to a server. In this case we will deploy our files through an FTP connection to our server. We can do this through the build in FTP client in Visual Studio or with an FTP client of choice (&lt;a href="https://filezilla-project.org/"&gt;FileZilla&lt;/a&gt;, ...)&lt;/p&gt;

&lt;h3&gt;
  
  
  Create application folder on our server
&lt;/h3&gt;

&lt;p&gt;We'll deploy our app to the &lt;strong&gt;/var/www/&lt;/strong&gt; directory from our server. But this doesn't exist yet, so we have to create this folder. We also need to give access to our user we've created and to the &lt;strong&gt;www-data&lt;/strong&gt; user. This www-data user will be used to run the app.&lt;/p&gt;

&lt;p&gt;Type in following commands in PowerShell and replace &lt;strong&gt;&lt;/strong&gt; with the name u want to use for your app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir /var/www/
sudo mkdir /var/www/
sudo chown -R dries:www-data /var/www/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install an FTP server on Ubuntu
&lt;/h3&gt;

&lt;p&gt;We will install an FTP (File Transfer Protocol) server on Ubuntu so we can transfer our files to Ubuntu.&lt;/p&gt;

&lt;p&gt;Make sure that our system packages are up to date by running following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's time to install an FTP server. We will using the common open-source FTP utility &lt;strong&gt;vsftpd&lt;/strong&gt;. To install vsftpd enter the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install vsftpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter &lt;strong&gt;Y&lt;/strong&gt; to continue&lt;/p&gt;

&lt;p&gt;Now start vsftpd by entering following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start vsftpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make sure that vsftpd is launched and enabled at startup entering following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl enable vsftpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your FTP client of choice (for me this is FileZilla) and make a connection by entering the IP address from your server and your credentials (in my case user &lt;strong&gt;dries&lt;/strong&gt; ). Now check if you have access to the following path: &lt;strong&gt;/var/www/&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EK7ba3II--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/filezilla-connection-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EK7ba3II--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/filezilla-connection-01.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to config vsftpd so we can upload files. At this moment we can only read files from the server but not upload any file. Open the vsftpd configuration file through PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/vsftpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the entry &lt;strong&gt;write_enable=YES&lt;/strong&gt; and uncomment this line. Don't forget to save this configuration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8jJLgYYU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/vsftpd-write-enable-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8jJLgYYU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/vsftpd-write-enable-01.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now restart the vsftpd service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart vsftpd.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Publish our web application
&lt;/h3&gt;

&lt;p&gt;Now open a new PowerShell window and navigate to your solution folder:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mZLUuhv8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mZLUuhv8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-01.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Type in the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something similar like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DJNeIYew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DJNeIYew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-02.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now open your Windows Explorer and navigate to the following folder: &lt;strong&gt;\bin\Debug\netcoreapp3.1\publish&lt;/strong&gt;. You'll see that this folder contains several files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wwq3PXhO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wwq3PXhO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-03.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These files and folders need to be uploaded to our server. Select all the files and folders and move/drag them to the &lt;strong&gt;/var/www/&lt;/strong&gt; folder on the server through an FTP-client.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--493BBYX0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--493BBYX0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/dotnet-publish-04.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything worked correctly, our app is now ready to run. But if you enter the IP address of your server in a web browser, you will see that this is not working (yet!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---zPteIOn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/nginx-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---zPteIOn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/nginx-01.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are almost there! We just need to install a web server on Ubuntu. Let's do that next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and configure NGINX in Ubuntu
&lt;/h2&gt;

&lt;p&gt;Now it's time to install a NGINX webserver and setup a reverse proxy. A reverse proxy will forward requests made to our server to our app. As a webserver we will use &lt;a href="https://www.nginx.com/"&gt;NGINX&lt;/a&gt; and for the configuration of our reverse proxy server we will follow the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-3.1#configure-a-reverse-proxy-server"&gt;Microsoft documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install NGINX
&lt;/h3&gt;

&lt;p&gt;We follow the &lt;a href="https://www.nginx.com/resources/wiki/start/topics/tutorials/install/#official-debian-ubuntu-packages"&gt;NGINX documentation&lt;/a&gt; to install NGINX on our Ubuntu release.&lt;/p&gt;

&lt;p&gt;We first need to add the repository to our &lt;strong&gt;source.list&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/apt/sources.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the bottom of the file add following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deb http://nginx.org/packages/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/ubuntu/ xenial nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit and save the file. Then enter following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run NGINX though following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service nginx start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the IP address from your server in your browser. You should see the default NGINX welcome page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2ya9KoHV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/nginx-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2ya9KoHV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/nginx-02.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add an SSL certificate with Certbot (if you have a domain name!)
&lt;/h3&gt;

&lt;p&gt;When you have a domain name that you can redirect to your IP address then you can secure your website with an SSL certificate from &lt;a href="https://letsencrypt.org/"&gt;Let's Encrypt&lt;/a&gt; by using &lt;a href="https://certbot.eff.org/"&gt;Certbot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you haven't a domain name, then skip this step.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the Certbot PPA and install with following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next run the following command and enter your e-mail address when asked. Agree with the Terms of Service by typing &lt;strong&gt;A&lt;/strong&gt; and add your domain name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot --nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Forward requests to our app
&lt;/h2&gt;

&lt;p&gt;Now it's time to forward the requests to our app instead of the NGINX welcome page.&lt;/p&gt;

&lt;p&gt;Enter following command to configure this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/nginx/sites-available/default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the content of that file with following text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name ;
    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to enable the site by linking it to &lt;strong&gt;/etc/nginx/sites-enabled/default&lt;/strong&gt; with following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now need to ensure that the default site is included in the http section of the NGINX config file. Edit the file with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/nginx/nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And below, where you'll find&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following line below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http{
    ...
    include /etc/nginx/sites-available/default;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now restart NGINX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now start the app by the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet //.dll
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case this command will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet /var/www/driesdeboosere-dev-demo-web/DriesDeboosere.Dev.Demo.Web.dll
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type in your browser your IP address now and you should see your website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--paZA_GTI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/nginx-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--paZA_GTI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://driesdeboosere.dev/blog/files/how-to-deploy-aspnet-core-31-app-to-digital-ocean-linux-droplet/nginx-03.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create service
&lt;/h3&gt;

&lt;p&gt;The next task is to set up our web application to run as a service, so you don't have to be logged in to your server for your application to run. Ubuntu uses &lt;strong&gt;systemd&lt;/strong&gt; by default for managing services. So first we need to create a service file (remember the name of the file as this is what you will reference to control it) by entering following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/systemd/system/.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/systemd/system/driesdeboosere-dev-demo-web.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the service information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=My application service

[Service]
WorkingDirectory=/var/www/
ExecStart=/usr/bin/dotnet /var/www//.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=My application service

[Service]
WorkingDirectory=/var/www/driesdeboosere-dev-demo-web
ExecStart=/usr/bin/dotnet /var/www/driesdeboosere-dev-demo-web/DriesDeboosere.Dev.Demo.Web.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=driesdeboosere-dev-demo-web
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Give read, write and execute rights to the folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown -R : /var/www/
sudo setfacl -R -d -m u::rwx,g::rwx,o::r /var/www/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown -R dries:dries /var/www/
sudo setfacl -R -d -m u:dries:rwx,g:dries:rwx,o::r /var/www/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start the service with following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or in my case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service driesdeboosere-dev-demo-web start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if it's running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl | grep 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or in my case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl | grep driesdeboosere-dev-demo-web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! Now your web server will keep running your ASP.NET Core app, even if you exit the server.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>csharp</category>
      <category>linux</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
