C# Archives - TEKSpace Blog https://blog.tekspace.io/tag/c/ Tech tutorials for Linux, Kubernetes, PowerShell, and Azure Mon, 21 Aug 2023 15:19:24 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 https://blog.tekspace.io/wp-content/uploads/2023/09/cropped-Tekspace-logo-icon-32x32.png C# Archives - TEKSpace Blog https://blog.tekspace.io/tag/c/ 32 32 Hosting ASP.NET Core 2.1 application on CentOS 7 with NGINX https://blog.tekspace.io/hosting-asp-net-core-2-1-application-on-centos-7-with-nginx/ https://blog.tekspace.io/hosting-asp-net-core-2-1-application-on-centos-7-with-nginx/#respond Mon, 19 Nov 2018 02:37:08 +0000 https://blog.tekspace.io/index.php/2018/11/18/hosting-asp-net-core-2-1-application-on-centos-7-with-nginx/ In this tutorial, I will demonstrate how to setup web hosting for ASP.NET Core 2.1 application in CentOS 7 Linux operating system using NGINX web hosting platform. Before we proceed, let’s make sure the system is up-to-date. Follow below steps. Setup NGINX and Firewall If it returned running. That means firewalld service is in running

The post Hosting ASP.NET Core 2.1 application on CentOS 7 with NGINX appeared first on TEKSpace Blog.

]]>
In this tutorial, I will demonstrate how to setup web hosting for ASP.NET Core 2.1 application in CentOS 7 Linux operating system using NGINX web hosting platform.

Before we proceed, let’s make sure the system is up-to-date. Follow below steps.

  1. Update CentOS 7 Linux.
sudo yum update -y
  1. Install epel-release package to install NGINX
sudo yum install epel-release -y

Setup NGINX and Firewall

  1. Install NGINX and firewalld.
sudo yum install nginx firewalld -y
  1. Start firewalld service.
sudo systemctl start firewalld.service
  1. Check firewalld status.
sudo firewall-cmd --state

If it returned running. That means firewalld service is in running state.

  1. Enable http and https to allow access from firewalld.
sudo firewall-cmd --permanent --zone=public --add-service=httpsudo firewall-cmd --permanent --zone=public --add-service=https

Once you execute below commands, you should see success in return for each command.

Lets go ahead and reload firewalld to apply new changes.

  1. Reload firewalld.
sudo firewall-cmd --reload
  1. Enable NGINX and firewalld to start on system reboot.
sudo systemctl enable nginxsudo systemctl enable firewalld.service

Setting up directory structure for hosting ASP.NET Core application

I like hosting my apps in /home/vhost. If you like to change this structure to something else, feel free to update below commands and all the references in NGINX configuration files.

  1. Create directory structure.
sudo mkdir -p -- /home/vhost /home/vhost/ssl/demo /home/vhost/www /home/vhost/www/demo

The above command will create the following structure.

  • /home/vhost will be root directory for hosting SSL configurations and application.
  • /home/vhost/ssl will be used for storing all SSL certificates for an application. For example, my application is called demo and I have created demo directory that will maintain all my certifications.
  • /home/vhost/www will be used for deploying applications. In my example, I have demo application. If you would like to setup server for multiple application you may create another directory and deploy application in it.
  1. Navigate to /home/vhost/www. And change ownership of demo folder to allow nginx to be owner of it.
cd /home/vhost/wwwsudo chown nginx:nginx -R demo

Install dotnet sdk

In order to run ASP.NET Core application in CentOS, we need to install dotnet sdk. Follow below steps:

  1. Install rpm package.
sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
  1. Install dotnet sdk.
sudo yum install dotnet-sdk-2.1

Configure NGINX and ASP.NET Core hosting

Hosting configuration

  1. Create config file for hosting demo application.
sudo vi /etc/nginx/conf.d/demo.conf

Press i to go into edit more in vi editor.

  1. Copy and paste the below settings into demo.conf file.
upstream demo{
        server localhost:5000;
    }
	# Redirect HTTP traffic to HTTPS.
    server {
        listen *:80;
        add_header Strict-Transport-Security max-age=15768000;
        return 301 https://$host$request_uri;
    }
	# Configure HTTPS
    server {
        listen *:443    ssl;
		# Replace HOSTNAME with actual domain name that will be used to access site from external.
        server_name     <HOSTNAME>;
		# Path to certificate file
        ssl_certificate /home/vhost/ssl/demo/demo.crt;
		# Path to Certificate key
        ssl_certificate_key  /home/vhost/ssl/demo/demo.key;
        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_ecdh_curve secp384r1;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;
        ssl_stapling on; #ensure your cert is capable
        ssl_stapling_verify on; #ensure your cert is capable

        add_header Strict-Transport-Security "max-age=63072000; includeSubdomain                   s; preload";
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

        #Redirects all traffic
        location / {
            proxy_pass  http://demo;
#            limit_req   zone=one burst=10;
        }
    }

On line 14 server_name replace <HOSTNAME> with actual dns alias your application will be accessible from outside. For example, if it is demo.example.com, replace it with this value.

On line 16 and 18, make sure to have correct certificates in placefor HTTPS traffic encryption and decryption.

Save the file by pressing :wq.

  1. Navigate to /etc/nginx.
cd /etc/nginx
  1. Take backup of nginx.conf file.
sudo cp nginx.conf nginx.conf_bk
  1. Edit nginx.conf
sudo vi nginx.conf

press i to enter in edit more.

  1. Enter below entry within http {}
http {
   include     /etc/nginx/proxy.conf;
}
  1. Comment out entire server {} block.
    #server {
    #    ....
    #}
  1. Save the file by pressing :wq.

nginx.conf should look like this:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    include     /etc/nginx/proxy.conf;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

Proxy configuration

  1. Create new file called proxy.conf.
sudo vi /etc/nginx.proxy.conf

Press i to be in edit mode.

  1. Copy and paste below entry.
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    include     /etc/nginx/proxy.conf;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

Save the file by pressing :wq.

Deploy and configure ASP.NET Core application

Go ahead and publish your application in your local file system. Once publish, copy all files and folder to /home/vhost/www/demo. Once copied, execute below command to change ownership.

cd /home/vhost/www
sudo chown nginx:nginx -R /home/vhost/www/demo

Create service to run ASP.NET Core application

  1. Execute the below command to create service.
sudo vi /etc/systemd/system/demo.service

Press i to go in edit mode.

  1. Copy and paste the below values.
[Unit]
    Description=Demo .NET Web API Application running on CentOS 7

    [Service]
    WorkingDirectory=/home/vhost/www/demo
    ExecStart=/usr/bin/dotnet /home/vhost/www/demo/Demo.dll
    Restart=always
    RestartSec=20 # Restart service after 10 seconds if dotnet service crashes
    SyslogIdentifier=dotnet-demo
    User=nginx
    Environment=ASPNETCORE_ENVIRONMENT=Production

    [Install]
    WantedBy=multi-user.target

Save the file by pressing :wq.

  1. Start the service.
sudo systemctl start demo
  1. Check the status of the service.
sudo systemctl status demo

The output should look as shown below.

● demo.service - Demo .NET Web API Application running on CentOS 7
   Loaded: loaded (/etc/systemd/system/demo.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2018-11-18 21:08:46 UTC; 5s ago
 Main PID: 18390 (dotnet)
   CGroup: /system.slice/demo.service
           └─18390 /usr/bin/dotnet /home/vhost/www/demo/Demo.dll

Nov 18 21:08:46 demo.example.com systemd[1]: [/etc/systemd/sys...
Nov 18 21:08:46 demo.example.com systemd[1]: Started Demo ....
Nov 18 21:08:46 demo.example.com systemd[1]: Starting Demo ...
Nov 18 21:08:47 demo.example.com dotnet-demo[18390]: warn: ...
Nov 18 21:08:47 demo.example.com dotnet-demo[18390]: No XML...
Nov 18 21:08:48 demo.example.com dotnet-demo[18390]: Hostin...
Nov 18 21:08:48 demo.example.com dotnet-demo[18390]: Conten...
Nov 18 21:08:48 demo.example.com dotnet-demo[18390]: Now li...
Nov 18 21:08:48 demo.example.com dotnet-demo[18390]: Applic...
Hint: Some lines were ellipsized, use -l to show in full.
  1. Enable service on reboot.
sudo systemctl enable demo.service

Finally, before we test the application from outside. We need to disable SELinux.

Disable SELinux

  1. Edit selinux file
sudo vi /etc/sysconfig/selinux

Press i to go in edit mode.

  1. Find SELINUX=enforcing and replace it with SELINUX=disabled.
  2. Reboot your system.
sudo reboot

Once the system comes on. You should be able to browse the application from another computer.

The post Hosting ASP.NET Core 2.1 application on CentOS 7 with NGINX appeared first on TEKSpace Blog.

]]>
https://blog.tekspace.io/hosting-asp-net-core-2-1-application-on-centos-7-with-nginx/feed/ 0
Code First Multiple DB Context Migration https://blog.tekspace.io/code-first-multiple-db-context-migration/ https://blog.tekspace.io/code-first-multiple-db-context-migration/#respond Sat, 03 Feb 2018 02:51:47 +0000 https://blog.tekspace.io/index.php/2018/02/03/code-first-multiple-db-context-migration/ In Entity Framework Core 2.0, you can implement multiple DbContext and apply changes to one single database by using multiple projects. For instance, you are planning to add schema from a third party project to your own project. Your requirement is to add those schemas to your single database. It can be any database; for

The post Code First Multiple DB Context Migration appeared first on TEKSpace Blog.

]]>
In Entity Framework Core 2.0, you can implement multiple DbContext and apply changes to one single database by using multiple projects. For instance, you are planning to add schema from a third party project to your own project.

Your requirement is to add those schemas to your single database. It can be any database; for example SqlLite, SQLServer, or MySQL.

In this tutorial, I will be using SQLServer with EntityFramework Core 2.0. Below are 3 projects with their own DbContext. You can find this project on GitHub here.

  • BookRental
  • StudentRegistration
  • MultipleDbContextExample

BookRental project contains two entities, called “Author” and “Book”.
The StudentRegistration project comprises a single entity named “Student.”
MultipleDbContextExample project contains default ASP.NET core individual authentication DbContext that will have its own entities.

In the MultipleDbContextExample, we will include the DbContexts from the BookRental and StudentRegistration projects. That will add all the entities to one single database.

Here are DbContexts from individual projects. I would assume that you already know how to create models, entities, etc. This tutorial will give you a high level overview of how to apply migrations to one single SQL database.

BookRental project DbContext
namespace BookRental.Models
{
    public class BookRentalDbContext : DbContext
    {
        public BookRentalDbContext (DbContextOptions<BookRentalDbContext> options)
            : base(options)
        {
        }

        public DbSet<BookRental.Models.Author> Author { get; set; }
        public DbSet<BookRental.Models.Book> Book { get; set; }
    }
}
StudentRegistration project DbContext
namespace StudentRegistration.Models
{
    public class StudentRegistrationDbContext : DbContext
    {
        public StudentRegistrationDbContext(DbContextOptions<StudentRegistrationDbContext> options)
            : base(options)
        {
        }

        public DbSet<StudentRegistration.Models.Student> Student { get; set; }
    }
}
MultipleDbContextExample project DbContext
namespace MultipleDbContextExample.Data
{
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            // Customize the ASP.NET Identity model and override the defaults if needed.
            // For example, you can rename the ASP.NET Identity table names and more.
            // Add your customizations after calling base.OnModelCreating(builder);
        }
    }
}

Now we have DbContext from each project. Let’s go ahead and make modifications to startup.cs file in MultipleDbContextExample project that will maintain one single instance of SQL database.

In ConfigureServices DI, I have defined two DbContext for BookRentalDbContext and StudentRegistrationDbContext.

public void ConfigureServices(IServiceCollection services)
{
    // Default ASP.NET Authentication DbContext
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    // BookRentalDbContext from BookRental project
    services.AddDbContext<BookRentalDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.MigrationsAssembly("MultipleDbContextExample"))
    );

    // StudentregistrationDbContext from StudentRegistration project
    services.AddDbContext<StudentRegistrationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.MigrationsAssembly("MultipleDbContextExample"))
    );
    // Add application services.
    services.AddTransient<IEmailSender, EmailSender>();

    services.AddMvc();
}

Once you have defined your own DbContext in the startup file, we will apply migration that will create tables in the database. Execute the below commands from a PowerShell console. Make sure to be in MultipleDbContextExample project and execute the below commands.

Default Db migration from MultipleDbContextExample project.

Update-Database -Context ApplicationDbContext

Add migration from BookRentalDbContext DbContext.

Add-Migration InitialBookRentalDbMigration -Context BookRentalDbContext -o Data/Migrations/BookRental/BookRentalDBUpdate-Database -Context BookRentalDbContext

Add migration from StudentRegistrationDbContext DbContext.

Add-Migration InitialStudentRegistrationDbMigration -Context StudentRegistrationDbContext -o Data/Migrations/StudentRegistration/StudentRegistrationDBUpdate-Database -Context StudentRegistrationDbContext

Once you have executed the above command, you will see tables created in the database.

The post Code First Multiple DB Context Migration appeared first on TEKSpace Blog.

]]>
https://blog.tekspace.io/code-first-multiple-db-context-migration/feed/ 0