终于将“.NET跨平台之旅”的示例站点 about.cnblogs.com 从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0 ,经历了不少周折,在这篇博文中记录一下。

从 ASP.NET 5 到 ASP.NET Core 最大的变化,除了改名之外,就是用 dotnet cli(命令名是dotnet)取代了dnx。所以运行 ASP.NET Core 程序,首先要安装 dotnet cli,我们是在 Ubuntu 服务器上用 apt-get install dotnet 命令安装的。

运行 ASP.NET 5 程序的命令是 dnx restore + dnx web,运行 ASP.NET Core 程序的命令则变为 dotnet restore + dotnet run。dotnet 运行 ASP.NET 程序 与 dnx 有一个很大的不同,除了 project.json 与 Startup.cs 职位,还需要一个 Program.cs 。

用 dnx 运行 ASP.NET 5 程序,需要在 project.json 中配置相应的 command ,比如:

"commands":{
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://*:8001"
}

而在 ASP.NET Core 中,不再需要这个 command ,而是交由 Program.cs 负责,比如我们这个示例项目中所用的 Program.cs 代码如下:

using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder; namespace CNBlogs.AboutUs.Web
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseServer("Microsoft.AspNetCore.Server.Kestrel")
.UseUrls("http://*:8001")
.UseApplicationBasePath(Directory.GetCurrentDirectory())
.UseDefaultConfiguration(args)
.UseIISPlatformHandlerUrl()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}

从上面的代码可以看出,ASP.NET Core 应用的启动工作是由 WebHostBuilder(源码)起头的,但它不是主角,只是助手,准备一些启动参数,最终把启动工作交给了真正的主角 —— WebHost,如果你对 WebHost 怎么干活的感兴趣,可以看它的 源码

弄好 Program.cs 之后,接下来就是体力活 —— 改名。

  • EntityFrameworkCore.MicrosoftSqlServer 改为 Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.AspNet.Builder 改为 Microsoft.AspNetCore.Builder
  • Microsoft.Data.Entity 改为 Microsoft.EntityFrameworkCore
  • Microsoft.AspNet.Mvc 改为 Microsoft.AspNetCore.Mvc
  • Microsoft.AspNet.Html.Abstractions 改为 Microsoft.AspNetCore.Html
  • 移除 Microsoft.Dnx.Runtime 命名空间
  • 等等

完成“改名”体力活之后,接下来的工作最费周折最累人 —— 配置 project.json , 而且现在的 project.json 不支持注释,调测配置变得更麻烦。

首先要在 project.json 中添加如下 emitEntryPoint 的配置,dnx 时期不加是可以的,现在可不行。

"compilationOptions": {
"emitEntryPoint": true
}

遇到的第一问题是 dotnet restore 时出现 not compatible with DNXCore,Version=v5.0 错误。。。后来通过在 project.json 中添加如下的配置解决了,但至今未能弄明白为什么加上看似这个不相关的配置能解决问题(或者只是表面地解决)。

"tools": {
"dotnet-publish-iis": "1.0.0-*"
}

遇到的第二个问题是 The dependency Ix-Async 1.2.5 does not support framework DNXCore,Version=v5.0 。这个问题与 Entity Framework 有关,只要在 project.json 的 dependencies 中去掉 "Microsoft.EntityFrameworkCore.SqlServer",问题就消失。后来参考 Entity Framework 的源代码,在 project.json 中添加如下的配置才解决问题:

"netstandard1.3": {
"imports": [
"dotnet5.4",
"portable-net452+win81"
]
}

接下来遇到的问题是 ASP.NET Core MVC 路由匹配问题 ,用 dotnet run 将站点运行起来后,访问任何URL都出现404错误。这是一个让人无从下手的问题,因为从 Startup.cs 中的代码看,MVC的配置无任何问题。后来还是怀疑到可能是 project.json 的问题,于是与 dotnet-cli 的示例项目 cli-samples 中的 project.json 进行对比,试了试添加如下的配置,问题竟然奇迹般地解决了(这个配置当时没有去进一步研究)。

{
"compilationOptions": {
"preserveCompilationContext": true
}
}

最后一个问题最让人无语,问题是 访问ASP.NET Core MVC站点出错:Could not load file or assembly 'Microsoft.Win32.Registry' 。不仅我们的项目有这个问题,而且 cli-samples 中的 HelloMvc 项目也有这个问题。问题发生在 Microsoft.AspNetCore.DataProtection 中,而且 DataProtectionServices.cs 中的确引用了 Microsoft.Win32.Registry,但是我们是在 Linux 上运行的,难道 Microsoft.AspNetCore.DataProtection 目前还不支持跨平台?

整个升级进程就在这里卡住了,当我们正准备暂时放弃升级至 ASP.NET Core 1.0 的时候,昨天发现 cli-samples 中的 prject.json 更新了,然后试着运行了一下 HelloMvc 项目,问题竟然神奇地解决了。立马看一下对应的 git commit

原来在 dependecies 中删除了 NETStandard.Library ,在 frameworks 中添加了 netstandardapp1.3 的配置。于是,照着这个修改了我们项目中的 project.json ,问题立马解决,我们的.NET跨平台之旅的示例站点 about.cnblogs.com 也就成功运行了起来,升级总算成功完成了。

分享一下这个示例项目中的三个文件:

project.json:

{
"compilationOptions": {
"preserveCompilationContext": true,
"emitEntryPoint": true
},
"dependencies" : {
"Microsoft.Extensions.Logging.Console": "1.0.0-*",
"Microsoft.AspNetCore.IISPlatformHandler": "1.0.0-*",
"Microsoft.AspNetCore.HttpOverrides": "1.0.0-*",
"Microsoft.AspNetCore.Mvc": "1.0.0-*",
"Microsoft.AspNetCore.StaticFiles": "1.0.0-*",
"Microsoft.AspNetCore.Diagnostics": "1.0.0-*",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*",
"System.Runtime.Serialization.Primitives": "4.1.0-*",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-*"
},
"frameworks": {
"netstandardapp1.3": {
"dependencies": {
"NETStandard.Library": "1.0.0-*"
},
"imports": [
"dnxcore50",
"portable-net45+win8"
]
}
},
"tools": {
"dotnet-publish-iis": "1.0.0-*"
}
}

Startup.cs:

namespace CNBlogs.AboutUs.Web
{
public class Startup
{
public Startup(IApplicationEnvironment appEnv)
{
IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(appEnv.ApplicationBasePath)
.AddJsonFile("config.json", false);
Configuration = builder.Build();
} public IConfiguration Configuration { get; set; } public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(LogLevel.Debug);
app.UseDeveloperExceptionPage();
app.UseMvcWithDefaultRoute();
app.UseStaticFiles();
app.UseRuntimeInfoPage();
} public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<EfDbContext>(options =>
{
options.UseSqlServer(Configuration["data:ConnectionString"]);
}); services.AddTransient<ITabNavRepository, TabNavRepository>();
services.AddTransient<ITabNavService, TabNavService>();
}
}
}

NuGet.Config:

<configuration>
<packageSources>
<clear />
<add key="AspNetCI" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

.NET跨平台之旅:将示例站点从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0的更多相关文章

  1. .NET跨平台之旅:在Linux上以本地机器码(native)运行ASP.NET Core站点

    在将“.NET跨平台之旅”示例站点 about.cnblogs.com 从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0 (博文链接)之后,我们有一个难以抗拒的冲动 —— 体验 ...

  2. .NET跨平台之旅:探秘 dotnet run 如何运行 .NET Core 应用程序

    自从用 dotnet run 成功运行第一个 "Hello world" .NET Core 应用程序后,一直有个好奇心:dotnet run 究竟是如何运行一个 .NET Cor ...

  3. .NET跨平台之旅:基于.NET Core改写EnyimMemcached,实现Linux上访问memcached缓存

    注:支持 .NET Core 的 memcached 客户端 EnyimMemcachedCore 的 NuGet 包下载地址:https://www.nuget.org/packages/Enyim ...

  4. .NET跨平台之旅:增加文件日志功能遇到的挫折

    在将我们的ASP.NET 5示例站点(about.cnblogs.com)升级至ASP.NET 5 RC1的时候,我们增加了控制台日志功能. 在ASP.NET 5添加日志功能很简单,只需在projec ...

  5. .NET跨平台之旅:成功将示例站点升级至ASP.NET Core RC2

    ASP.NET Core RC2 终于发布了( Announcing ASP.NET Core RC2 ).为了庆祝这次发布,我们将运行在 Ubuntu 服务器上的示例站点 about.cnblogs ...

  6. .NET跨平台之旅:升级ASP.NET Core示例站点

    ASP.NET Core示例站点网址:http://about.cnblogs.com/ 首先安装最新版的 .NET Core 运行环境,从 https://github.com/dotnet/cli ...

  7. .NET跨平台之旅:将示例站点从ASP.NET 5 Beta5升级至Beta7

    9月2日,微软发布了ASP.NET 5 Beta7(详见Announcing Availability of ASP.NET 5 Beta7).其中最大的亮点是dnx已经可以完全基于CoreCLR运行 ...

  8. .NET跨平台之旅:将示例站点升级至 ASP.NET Core 1.1

    微软今天在 Connect(); // 2016 上发布了 .NET Core 1.1 ,ASP.NET Core 1.1 以及 Entity Framework Core 1.1.紧跟这次发布,我们 ...

  9. .NET跨平台之旅:将示例站点升级至 .NET Core 1.1 Preview 1

    今天微软发布了 .NET Core 1.1 Preview 1(详见 Announcing .NET Core 1.1 Preview 1 ),紧跟 .NET Core 前进的步伐,我们将示例站点 h ...

随机推荐

  1. Rafy 框架-发布网页版用户手册

    前段时间把 Rafy 的用户手册由 CHM 格式转换为了网页格式,而且发布到了 github.io 上,即方便文档的实时更新,也方便大家查看. Rafy 用户手册网页版地址: http://zgynh ...

  2. 你所不知道的linq(二)

    上一篇说了from in select的本质,具体参见你所不知道的linq.本篇说下from...in... from... in... select 首先上一段代码,猜猜结果是什么? class P ...

  3. Linq to sql 有什么办法可以实现消除列重复?

    比如数据库里有一表,有两个字段:ID User1 小白2 小红3 小白 过滤User列为小白的重复项后,我想要得到:ID User1 小白2 小红 如果写db.linq.customer.Distin ...

  4. 共享Excel编辑的一些资源

    官方资料: 使用共享工作簿进行协作 相关介绍文章: http://www.ittribalwo.com/article/678.html http://www.wuji8.com/meta/85646 ...

  5. SQL中varchar和nvarchar的区别

    varchar(n)长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 1 和 8,000 之间的数值.存储大小为输入数据的字节的实际长度,而不是 n 个字节. nvar ...

  6. html5上传图片(一)一跨域上传

    最近开发一个上传图片的模块,传图片的接口不支持跨域上传,并且只支持单张上传,而我们的产品要求要实现多张上传.我搞了一个代理页面,先将图片传到代理页面,然后再通过代理页面传到上传图片接口.虽然这种方式经 ...

  7. xampp与Hbuilder、phpstorm配置

    1.xampp的安装就不用多说了,安装完按之后出现这个界面. 2.点击中间那个按钮,运行三个选项,全部正常之后是这样的,这样xampp就不用管了,但是要记下安装的路径,之后需要用 3.首先说Hbuil ...

  8. jQuery实现DOM加载方法源码分析

    传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... }  但 ...

  9. javascript浏览器检测

    <script type="text/javascript">   /**  * 获取浏览器类型以及版本号  * 支持国产浏览器:猎豹浏览器.搜狗浏览器.傲游浏览器.3 ...

  10. Android任务栈的运行规律

    一:前台栈表示应用A,后台栈则是应用B 前台栈/taskAffinity/launchMode 后台栈/taskAffinity/launchMode ActivityB/com.lpn.teston ...