【原生态跨平台:ASP.NET Core 1.0(非Mono)在 Ubuntu 14.04 服务器上一对一的配置实现-篇幅1】

时间:2022-03-08 04:26:03

-----------------2017年了 下面的都是老版本的了.无语ing------------------------

asp.net core 正处于快速成长期,按照官方的路线,2017年的 第三个季度,大概就是10月份了。2.0正式版 面世。估计那时候就可以愉快的玩耍了。。。。。。

Release Time frame*
2.0-preview1 Q2 2017
2.0-preview2 Q2 2017
2.0 Q3 2017
2.1 Q4 2017

Release Time frame*

最坑莫过于 project.json  呵呵 。。。。。。。。。。。。。。。。。。。。。

最新的 请看

Set up a hosting environment for ASP.NET Core on Linux with Nginx, and deploy to it

Ubuntu 14.04 的

【asp.net core】Publish to a Linux-Ubuntu 14.04 Server Production Environment

Publish to a Linux Production Environment

--------------------------------------------------

鸡冻人心的2016,微软高产年。

build 2016后 各种干货层出不穷。

1 Win10 集成了bash  ,实现了纳德拉的成诺,Microsoft Love Linux!!!

2 跨平台  ,收购Xamarin 。。还给开源了

3 Sqlserver有了Linux的版本...............

4 ASP.NET 5迎来第一个稳定版本,跨平台。在Windows Linux Mac OsX 中都能玩了.........

光说不练假把式,先上图一枚....

-------------------------省略图了,博客园上传图片失败,又粗问题了--------------------------

那各位,咱只能文字版本了。。。。

在借鉴了行内无数的博文后,决定尝试下。然而,随着前期,微软的asp.net core不断升级。。以前的基于Beta版本的  预览版本的博文可能都不再好用了。。

环境:Ubuntu 14.04 服务器版

虚拟机:Vmware 10

工具 :XShell

开发工具:VS2015企业版+ASP.NET Update1

反向代理:Nginx

是否用到了Docker?没,墙太高了,镜像拉不过来,秒懂!???!?!?!

Let us go!

Installing on Ubuntu 14.04

The following instructions were tested using Ubuntu 14.04. Other versions of Ubuntu and other Debian based distros are unlikely to work correctly.

去ubuntu官网下载此版本。微软号称1.0的Core  仅仅这个版本的Linux稳定。其他的,对不起,祝福你。。

下载地址:

http://releases.ubuntu.com/14.04/

完事后,创建虚拟机。。。

开始在Linux下 安装 ASP.NET Core

Install the .NET Version Manager (DNVM)
Use the .NET Version Manager (DNVM) to install different versions of the .NET Execution Environment (DNX) on Linux.

Install unzip and curl if you don’t already have them:

#安装过程中需要的工具

sudo apt-get install unzip curl

Download and install DNVM:

#安装DNVM  版本管理器

curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh

Once this step is complete you should be able to run dnvm and see some help text.

Install the .NET Execution Environment (DNX)
The .NET Execution Environment (DNX) is used to build and run .NET projects. Use DNVM to install DNX for Mono or .NET Core (see Choosing the Right .NET For You on the Server).

To install DNX for .NET Core:

Install the DNX prerequisites:

#安装DNX需要的工具

sudo apt-get install libunwind8 gettext libssl-dev libcurl4-openssl-dev zlib1g libicu-dev uuid-dev

Use DNVM to install DNX for .NET Core:

#安装最新版本的 DNX(现在是 1.0的update 2)

dnvm upgrade -r coreclr

#安装完毕后。执行下面的命令 ,查看dnx的安装目录。很重要哦,这是运行时。

which dnx

---------------------------完事后呢,开始搭建HTTP Server-----------------

内置的为 Kestrel,基于 Libuv。

安装 libuv

#!/usr/bin/env bash
sudo apt-get install make automake libtool curl
curl -sSL https://github.com/libuv/libuv/archive/v1.8.0.tar.gz | sudo tar zxfv - -C /usr/local/src
cd /usr/local/src/libuv-1.8.0
sudo sh autogen.sh
sudo ./configure
sudo make
sudo make install
sudo rm -rf /usr/local/src/libuv-1.8.0 && cd ~/
sudo ldconfig

-------------------------------好了,安装基本的ASP.NET CORE 1.0环境完毕了------------------------------

安装VS2015
安装最新发布的 asp.net 5更新补丁
创建web

发布到 ubuntu

#bash 命令 进入src/Your ProjetcName 目录,还原程序需要的依赖的组件包。组件包 都发布在微软的Nuget上。

#看看都有啥 https://www.myget.org/gallery/aspnetvnext

dnu restore
dnx web

***********注意上面的 web节点。。这个是在project.json中的commands节点。。************(如果不给 --server参数  默认就是 kestrel,默认端口是5000)

示范端口:(在RC2中 Kestrel 不能仅仅是用名称Kestrel,需要是全名!!!!!!!)
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5004",
"kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5004",
"ef": "EntityFramework.Commands"
},

这里有个钉子哦。。。。

-----localhost仅仅是本机访问的绑定,不能在本机外访问(是用Nginx 反向代理除外,稍后讲)
*:port 进行机器iP的绑定端口

------------------------------------------------------------------------

#好了,当执行了 dnx [node name ] 指令后,就可以访问站点了。

curl http://localhost:5000

#查看 dnx  是否运行中

ps -el|grep dnx

------------web  程序已经启动了,咋地管理呢?---------------

1 更新

2 暂停

3 启动

1 更新,只要更改了project.json文件,程序就自动更新了。

2 暂停 重启

dnx 没有对应的重启 Kestrel的命令...........
#如果出现端口占用重复的问题,那么直接杀死 dnx 监听的进程即可。。。。。
lsof -i :5004
kill -9 portnumber

重启是个麻烦事,每次都要进程序目录,有简单的方法吗,有!!!!!!一会儿讲Linux下的进程守护软件   supervisor !

有人说了,DD的,没法进行机器IP的访问啊!!!!

别着急呵呵呵呵~~~~~~~~~~~~防火墙你懂的。。。。

防火墙 打开对应的端口访问

sudo ufw allow 5000/tcp

-------------------------防火墙篇----------------

2、启用:

ufw enable

ufw default deny

3、开启/禁用:

ufw allow 22/tcp 允许所有的外部IP访问本机的22/tcp (ssh)端口

ufw deny 22/tcp 禁止所有外部IP访问本机的22/tcp(ssh)端口

ufw delete deny 22/tcp 删除防火墙中的规则

有时候关闭软件后,后台进程死掉,导致端口被占用。下面以JBoss端口8083被占用为例,列出详细解决过程。

解决方法:

1.查找被占用的端口

netstat -tln 
netstat -tln | grep 8083 
netstat -tln 查看端口使用情况,而netstat -tln | grep 8083 则是只查看端口8083的使用情况

2.查看端口属于哪个程序?端口被哪个进程占用

lsof -i :8083

3.杀掉占用端口的进程

kill -9 进程id

----------------------------------------

现在  是不是能机器IP + 端口的方式访问了?

好,我们开始说Nginx做反向代理。

等等  不是有了HTTP SERVER了??那个Kestrel ,确实是个Server 但是管理太麻烦啦,而且有些现有的模块,它都没有,so ,来吧,Nginx !!

Apache也行,你们自己找配置。。。。

#开始安装 Nginx

sudo apt-get install nginx

重新启动nginx:
sudo service nginx stop
sudo service nginx start
或者
sudo nginx -s reload
sudo service nginx restart

sudo ufw allow 80/tcp

Nginx is used as a reverse proxy for static contents in general and you can also enable gzip compression on your dynamic content. Kestrel doesn't have this feature.

Personally, I don't use Kestrel on Linux but firefly which is a managed HTTP server. I also wrote a fastCGI server for ASP.NET 5 but firefly is the best in the realm of performance.

sudo apt-get install nginx

#配置反向代理

vi /etc/nginx/sites-available/default

#try_files $uri $uri/ =404;-----------一定要注释掉这个配置节点 。我们的asp.net mvc是基于路由访问控制 而不是通过CGI文件(asp php py等)

server {
listen 80;
location / {
proxy_pass http:http://*: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_pass http://*:5004;
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;

接下来 就是nginx的配置了。。压缩 头信息 缓存 等等

nginx的配置是门艺术,你们懂的。。。我不再献丑了呵呵呵呵。

好了,机器IP 的80端口 也给它开放出来。然后,就机器IP在外部访问就好。

---------------------------------好,我们说说  Kestrel的 暂停 重启问题吧 呵呵呵呵---------------------------

自动启动Web
Monitoring our Web Application

Nginx will forward requests to your Kestrel server, however unlike IIS on Windows, it does not mangage your Kestrel process. In this tutorial, we will use supervisor to start our application on system boot and restart our process in the event of a failure.

Installing supervisor

#首先安装 supervisor ,进程守护

sudo apt-get install supervisor

To have supervisor monitor our application, we will add a file to the

#进入
cd /etc/supervisor/conf.d/

#创建 配置文件 kestrel_default.conf

[program:kestrel_default]
command=su -c "/root/.dnx/runtimes/dnx-coreclr-linux-x64.1.0.0-rc1-update2/bin/dnx web --server.urls=http://*:5004" root
directory=/home/www/test/src/BookStore/
autorestart=true
autostart=true
#stdout_logfile=/home/rodolfo/WebApplicationBasic/logs/app_std_out.log
#stderr_logfile=/home/rodolfo/WebApplicationBasic/app_err.log

******注意上面的,directory command 节点很重要。机器重启后,自动在指定的目录,执行对应的指令。 好吧,千万记得查询下,你的dnx的安装路径。

这个路径不是固定的,我是用的root用户登录的,然后给我安装到了这个地方。。。。。。。。。

*********

#配置完毕后,刷新supervisor的配置加载信息

sudo supervisorctl reread
sudo supervisorctl update
 
 
#开始对配置的集成进行管理
#Listar os processos configurados e o status
sudo supervisorctl
 
#Parar um processo
sudo supervisorctl stop kestrel_default
 
#iniciar um processo
sudo supervisorctl start kestrel_default
 
 

#大招是直接把 supervisor 停了,你懂的。
Once you are done editing the configuration file, restart the supervisord process to change the set of programs controlled by supervisord.

sudo service supervisor stop
sudo service supervisor start

----------------------------------嗯,基本一个完整的Web项目配置  管理完事了,性能还行,如何优化等,那是另一说了-----------------

至于镜像容器 Docker。。。。。嗯,我是没弄成功,你们自己搞,好像有弄成功的,我这边的访问不了官网的源,未能解析host ,我一看就知道啥意思 呵呵

各位好运。。。。。。

(完!)

顺便说一下,进程守护 可以监听多个ASP.NET CORE 程序,配置方案:

[program:kestrel_default]
command=su -c "/home/rodolfo/.dnx/runtimes/dnx-coreclr-linux-x64.1.0.0-rc1-update1/bin/dnx web --server.urls=http://0.0.0.0:5001" rodolfo
directory=/home/rodolfo/WebApplicationBasic
autorestart=true
autostart=true
stdout_logfile=/home/rodolfo/WebApplicationBasic/logs/app_std_out.log
stderr_logfile=/home/rodolfo/WebApplicationBasic/app_err.log [program:kestrel_default1]
command=su -c "/home/rodolfo/.dnx/runtimes/dnx-coreclr-linux-x64.1.0.0-rc1-update1/bin/dnx web --server.urls=http://0.0.0.0:5002" rodolfo
directory=/home/rodolfo/WebApplicationBasic
autorestart=true
autostart=true
stdout_logfile=/home/rodolfo/WebApplicationBasic/logs/app_std_out2.log
stderr_logfile=/home/rodolfo/WebApplicationBasic/app_err2.log [program:kestrel_default2]
command=su -c "/home/rodolfo/.dnx/runtimes/dnx-coreclr-linux-x64.1.0.0-rc1-update1/bin/dnx web --server.urls=http://0.0.0.0:5003" rodolfo
directory=/home/rodolfo/WebApplicationBasic
autorestart=true
autostart=true
stdout_logfile=/home/rodolfo/WebApplicationBasic/logs/app_std_out3.log
stderr_logfile=/home/rodolfo/WebApplicationBasic/app_err3.log [program:kestrel_default3]
command=su -c "/home/rodolfo/.dnx/runtimes/dnx-coreclr-linux-x64.1.0.0-rc1-update1/bin/dnx web --server.urls=http://0.0.0.0:5004" rodolfo
directory=/home/rodolfo/WebApplicationBasic
autorestart=true
autostart=true
stdout_logfile=/home/rodolfo/WebApplicationBasic/logs/app_std_out4.log
stderr_logfile=/home/rodolfo/WebApplicationBasic/app_err4.log

记住,玩Linux的命令语法,bash 的Shell命令查询去我前面的文章找。 离线 chm 你懂的。。哈哈 祝福各位。

附带资料索引:

Bookmarks

Bookmarks

书签栏

ASP.NET Cross

http://dotnet.github.io/

Microsoft Loves Linux | Windows Server Blog

Why Microsoft loves Linux | ZDNet

让我们 Core 在一起:ASP.NET Core & .NET Core - 开源中国社区

Project.json file · aspnet/Home Wiki · GitHub

Jexus 网站服务器和 ASP.NET 跨平台开发 – Half-Blood Programmer

Jexus 网站服务器和 ASP.NET 跨平台开发 - 小斌斌 - 博客园

Jexus Web Server - Home

ASP.NET跨平台从这里开始!

ASP.NET Core 1.0 入门——了解一个空项目 - 勤奋的小孩 - 博客园

惊鸿哥的港湾

Gallery - MyGet - Hosting your NuGet, Npm, Bower and Vsix packages

Get ASP.NET

Running ASPNET 5 and .NET Core on Linux - CodeProject

Using Docker ENV with ASP.NET 5 | .NET Liberty

ASP.NET 5 (vNext) Linux部署 - Charlie.Zheng - 博客园

Getting started with ASP.NET 5 and Docker | http://luukmoret.github.io

Shayne Boyer: Legion of Heroes: haproxy, nginx, Angular 2, ASP.NET Core, Redis and Docker

Deploy an ASP.NET Core app to a Docker container using Release Management

NGINX Reverse Proxy and Load Balancing for ASP.NET 5 Applications with Docker Compose - Tugberk Ugurlu's Blog

aguacongas (Olivier Lefebvre) · GitHub

Fun with ASP.NET 5, Linux & Docker, Part 3

ASP.NET 5 in Docker on Linux

Publish to a Linux Production Environment — ASP.NET documentation

Docker Dockerfile详解 - edwardsbean的专栏 - 博客频道 - CSDN.NET

常用docker命令,及一些坑 - edwardsbean的专栏 - 博客频道 - CSDN.NET

DOCKER windows 7 详细安装教程 - 初夏的专栏 - 博客频道 - CSDN.NET

Developing ASP.NET Apps in Docker Containers | Steve Lasker's Web Log – www.SteveLasker.com/Blog

我的随笔 - 博客后台 - 博客园

JS

Javascript的10个设计缺陷 - 阮一峰的网络日志

深入理解javascript原型和闭包(完结) - 王福朋 - 博客园

Playground · TypeScript

Why not using ASP.NET 5 default web server, Kestrel?

Managing ASP.NET 5 web applications with Kestrel isn’t easy, or isn’t as easy as managing virtual hosts
like Apache or Nginx. Each web application must be running on one process of the Kestrel web server.
It means that we can’t run two web applications on the same port. Also, unlike Apache or Nginx, we cannot
declare our web applications in configuration files, and launch them all with a single command. We have
to run “dnx web” in a terminal for every web application! What about HTTPS? Well, I’ve saw a Nuget package
for a HTTPS Kestrel version, but it doesn’t look like as easy to configure as the other popular web servers.

Like I said before, I really like Nginx. Nginx is very good for serving static files and passing other
requests to other web servers (reverse proxying), and in our case, Kestrel.

Installation

I’m assuming that you already have a .NET environment installed on your Linux distribution. If not,
follow the official documentation to install it: DNVM, the .NET version manager, and the .NET Core
DNX runtime. At this time, the RC2 of .NET Core isn’t working for me, so I’m using the RC1.

Nginx configuration

Now let’s create a nginx configuration for our web application. We are going to proxy every request
to the Kestrel web server except the assets such as Javascript, CSS, images and other static files.
Nginx is the best for serving static content. We are going to add a HTTP header to be sur that it’s
Nginx that served our static content and not Kestrel.

server {
# Port and domain
listen 80;
server_name aspnet.local;

# Path to the wwwroot folder
root /home/developer/projects/WebApplicationBasic/wwwroot;

# Static content
location ~ \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm|woff2|svg)$ {
expires 1d;
access_log off;
add_header X-Static-File true;
}

# Pass requests to Kestrel
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Connection "";
proxy_http_version 1.1;
}
}
The 19th and 20th lines are very important. It covers a bug found in the RC1 version of Kestrel.
If you don’t add them, your browser will wait for an answer forever even if the server has sent
the response. Have a look here to find more information about this bug.

Adding MySQL to an ASP.NET 5 project, using Visual Studio Code? This might help.

Posted on November 28, 2015 by Steve • 1 Comment

I’ve been working on learning ASP.NET 5 the last few weeks.  I like it.  It feels like a solid platform, and I especially like Visual Studio Code.  I’m discovering a few quirks, though, as is common when you’re learning a new thing.  This one in particular, how to add the MySQL connector to a project, I wanted to share the solution I found.

If you were using Visual Studio proper, it’d be straightforward to use the “manage packages” dialog to find and add the MySQL connector.  Visual Studio Code, however, doesn’t provide that dialog.  The way you can add MySQL, then, is by opening up project.json and finding the “dependencies” block.  Add a line for MySQL:

"dependencies": {
...
"MySql.Data": "6.9.8"
},

And then scroll down and find the “frameworks” block.  I removed the entry for “dnxcore50” and set up the entry for “dnx451” like so:

"frameworks": {
  "dnx451":  {
    "frameworkAssemblies": {
      "System.Data": "4.0.0.0"
    }
  }
},

You’ll want to be sure to rerun dnu restore as needed.  After that, your new MySqlConnection(); and dbh.Open(); statements should work as normal.

Hope this helps,

Steve

Blog

Using Entity Framework 6 and MySQL on ASP.NET 5 (vNext)

Visual Studio 2015 was recently released, and with it came a newer beta of ASP.NET 5 (formerly referred to as "ASP.NET vNext"). ASP.NET 5 is a complete rewrite of ASP.NET, focusing on being lightweight, composible, and cross-platform. It also includes an alpha version of Entity Framework 7. However, EF7 is not yet production-ready and does not support all features of EF6. One feature that is missing from EF6 is support for other database providers - Only SQL Server and SQLite are supported at this time.

I wanted to transition a site over to ASP.NET 5, but needed to continue using MySQL as a data source. This meant getting Entity Framework 6 running on ASP.NET 5, which is pretty much undocumented right now. All the documentation and tutorials for EF6 heavily relies on configuration in Web.config, which no longer exists in ASP.NET 5. In this post I'll discuss the steps I needed to take to get it running. An example project containing all the code in this post can be found at https://github.com/Daniel15/EFExample.

Since EF6 does not support .NET Core, we need to remove .NET Core support (delete "dnxcore50": { } from project.json). Once that's done, install the EntityFramework and MySql.Data.Entity packages, and add references to System.Data and System.Configuration. For this post, I'll be using this basic model and DbContext, and assume you've already created your database in MySQL:

1
2
3
4
5
6
7
8
9
10
11
12
public class MyContext : DbContext
{
    public virtual DbSet<Post> Posts { get; set; }
}
  
public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

Entity Framework 6 relies on the provider and connection string being configured in Web.config. Since Web.config is no longer used with ASP.NET 5, we need to use code-based configuration to configure it instead. To do so, create a new class that inherits fromDbConfiguration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration()
    {
        // Attempt to register ADO.NET provider
        try {
            var dataSet = (DataSet)ConfigurationManager.GetSection("system.data");
            dataSet.Tables[0].Rows.Add(
                "MySQL Data Provider",
                ".Net Framework Data Provider for MySQL",
                "MySql.Data.MySqlClient",
                typeof(MySqlClientFactory).AssemblyQualifiedName
            );
        }
        catch (ConstraintException)
        {
            // MySQL provider is already installed, just ignore the exception
        }
  
        // Register Entity Framework provider
        SetProviderServices("MySql.Data.MySqlClient", new MySqlProviderServices());
        SetDefaultConnectionFactory(new MySqlConnectionFactory());
    }
}

The first part of the configuration is a hack to register the ADO.NET provider at runtime, by dynamically adding a new configuration entry to the system.data section. The second part registers the Entity Framework provider. We also need to modify the configuration file to include the connection string. You can use any configuration provider supported by ASP.NET 5, I'm using config.json here because it's the default provider.

1
2
3
4
5
6
7
8
{
  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=localhost; Database=test; Uid=vmdev; Pwd=password;"
    }
  }
}

Now that we have the configuration, we need to modify the context to use it:

1
2
3
4
5
6
7
8
9
10
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContext : DbContext
{
    public MyContext(IConfiguration config)
        : base(config.Get("Data:DefaultConnection:ConnectionString"))
    {
    }
    // ...
}

An instance of IConfiguration will be automatically passed in by ASP.NET 5's dependency injection system. The final step is to registerMyContext in the dependency injection container, which is done in your Startup.cs file:

1
2
3
4
5
6
public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddScoped<MyContext>();
}

AddScoped specifies that one context should be created per request, and the context will automatically be disposed once the request ends. Now that all the configuration is complete, we can use MyContext like we normally would:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HomeController : Controller
{
    private readonly MyContext _context;
  
    public HomeController(MyContext context)
    {
        _context = context;
    }
  
    public IActionResult Index()
    {
        return View(_context.Posts);
    }
}

Hope you find this useful!

Until next time, 
— Daniel

Using EF6 with ASP.NET MVC Core 1.0 (aka MVC 6)

This week Microsoft announced that it is renaming ASP.NET 5 to ASP.NET Core 1.0.  In general I think this is a very good step.  Incrementing the version number from 4 to 5 for ASP.NET gave the impression that ASP.NET 5 was a continuation of the prior version and that a clean migration path would exist for upgrading apps from ASP.NET 4 to 5.  However, this did not reflect the reality that ASP.NET 5 was a completely different animal, re-written from the ground up, and that is has little to do architecturally with its predecessor.  I would even go so far as to say it has more in common with node.js than with ASP.NET 4.

You can download the code for this post from my Demo.AspNetCore.EF6 repository on GitHub.

Entity Framework 7, however, has even less in common with its predecessor than does MVC, making it difficult for developers to figure out whether and when they might wish to make the move to the new data platform.  In fact, EF Core 1.0 is still a work in progress and won’t reach real maturity until well after initial RTM.  So I’m especially happy that EF 7 has been renamed EF Core 1.0, and also that MVC 6 is now named MVC Core 1.0.

The problem I have with the name ASP.NET Core is that it implies some equivalency with .NET Core.  But as you see from the diagram below, ASP.NET Core will not only runcross-platform on .NET Core, but you can also target Windows with .NET Framework 4.6.

【原生态跨平台:ASP.NET Core 1.0(非Mono)在 Ubuntu 14.04 服务器上一对一的配置实现-篇幅1】

Note: This diagram has been updated to reflect that EF Core 1.0 (aka EF 7) is part of ASP.NET Core 1.0 and can target either .NET 4.6 or .NET Core.

It is extremely important to make this distinction, because there are scenarios in which you would like to take advantage of the capabilities of ASP.NET Core, but you’ll need to run on .NET 4.6 in order to make use of libraries that are not available on .NET Core 1.0.

So why would you want to use ASP.NET Core 1.0 and target .NET 4.6?

As I wrote in my last post, WCF Is Dead and Web API Is Dying – Long Live MVC 6, you should avoid using WCF for greenfield web services, because: 1) is it not friendly to dependency injection, 2) it is overly complicated and difficult to use properly, 3) it was designed primarily for use with SOAP (which has fallen out of favor), and 4) because Microsoft appears to not be investing further in WCF.  I also mentioned you should avoid ASP.NET Web API because it has an outdated request pipeline, which does not allow you to apply cross-cutting concerns, such as logging or security, across multiple downstream web frameworks (Web API, MVC, Nancy, etc).  OWIN and Katana were introduced in order to correct this deficiency, but those should be viewed as temporary remedies prior to the release of ASP.NET Core 1.0, which has the same pipeline model as OWIN.

The other important advantage of ASP.NET Core is that it completely decouples you from WCF, IIS and System.Web.dll.  It was kind of a dirty secret that under the covers ASP.NET Web API used WCF for self-hosting, and you would have to configure the WCF binding if you wanted implement things like transport security.  ASP.NET Core has a more flexible hosting model that has no dependence on WCF or System.Web.dll (which carries significant per-request overhead), whether you choose to host in IIS on Windows, or cross-platform in Kestrel on Windows, Mac or Linux.

A good example of why you would want to use ASP.NET Core 1.0 to target .NET 4.6 would be the ability to use Entity Framework 6.x.  The first release of EF Core, for example, won’t include TPC inheritance or M-M relations without extra entities.  As Rowan Miller, a program manager on the EF team, stated:

We won’t be pushing EF7 as the ‘go-to release’ for all platforms at the time of the initial release to support ASP.NET 5. EF7 will be the default data stack for ASP.NET 5 applications, but we will not recommend it as an alternative to EF6 in other applications until we have more functionality implemented.

This means if you are building greenfield web services, but still require the full capabilities of EF 6.x, you’ll want to use ASP.NET MVC Core 1.0 (aka MVC 6) to create Web API’s which depend on .NET 4.6 (by specifying “dnx451” in the project.json file).  This will allow you to add a dependency for the “EntityFramework” NuGet package version “6.1.3-*”.  The main difference is that you’ll probably put your database connection string in an*.json file rather than a web.config file, or you may specify it as an environment variable or retrieve it from a secrets store.  An appsettings.json file, for example, might contain a connection string for a local database file.

1
2
3
4
5
6
7
{
  "Data": {
    "SampleDb": {
      "ConnectionString": "Data Source=(localdb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\SampleDb.mdf;Integrated Security=True; MultipleActiveResultSets=True"
    }
  }
}

You can then register your DbContext-derived class with the dependency injection system of ASP.NET Core.

1
2
3
4
5
6
7
8
9
10
11
12
public void ConfigureServices(IServiceCollection services)
{
    // Add DbContext
    services.AddScoped(provider =&gt;
    {
        var connectionString = Configuration["Data:SampleDb:ConnectionString"];
        return new SampleDbContext(connectionString);
    });
 
    // Add framework services.
    services.AddMvc();
}

This will allow you to inject a SampleDbContext into the constructor of any controller in your app.

1
2
3
4
5
6
7
8
9
[Route("api/[controller]")]
public class ProductsController : Controller
{
    private readonly SampleDbContext _dbContext;
 
    public ProductsController(SampleDbContext dbContext)
    {
        _dbContext = dbContext;
    }

Lastly, you’ll need to provide some information to EF regarding the provider you’re using (for example, SQL Server, Oracle, MySQL, etc).  In a traditional ASP.NET 4.6 app you would have done that in app.config or web.config.  But in ASP.NET Core you’ll want to specify the provider in a class that inherits from DbConfiguration.

1
2
3
4
5
6
7
public class DbConfig : DbConfiguration
{
    public DbConfig()
    {
        SetProviderServices("System.Data.SqlClient", SqlProviderServices.Instance);
    }
}

Then you can apply a DbConfigurationType attribute to your DbContext-derived class, so that EF can wire it all together.

1
2
3
4
5
6
7
8
[DbConfigurationType(typeof(DbConfig))]
public class SampleDbContext : DbContext
{
    public SampleDbContext(string connectionName) :
        base(connectionName) { }
 
    public DbSet Products { get; set; }
}

You can download the code for this post from my Demo.AspNetCore.EF6 repository on GitHub.

The primary limitation of targeting .NET 4.6 with EF 6 is that you’ll only be able to deploy your web services on Windows.  The good news, however, is that you’ll be in a great position to migrate from EF 6 to EF Core 1.0 (aka EF 7) as soon as it matures enough to meet your needs.  That’s because the API’s for EF Core are designed to be similar to EF 6.  Then when you do move to EF Core, you’ll be able to use Docker to deploy your web services on Linux VM’s running in a Cloud service such as Amazon EC2, Google Compute Engine, or Microsoft Azure.

Share this: