就是这个烦人的图层,像打不跑的苍蝇

文章背景:对于.NET Core大家应该并不陌生, 从它被
宣布
到现在已经有1-2年的时间了,其比较重要的一个版本1.0 RC2 也即将发布。.Net
Core从一个一个的测试版到现在的RC2,经历了很多个大大小小的变化。特别是在RC1到RC2的更新之中,.NET
Core命令行工具(dotnet cli)从 dnx 变为 dotnet,并且废除了 DNVM 和
DNU,使得 .NET Core
的开发变得更为简单,其相关工具链也基本成型。虽然网上关于.NET
Core的示例项目不在少数,而且微软官方也提供了不少示例项目,但大多针对的是.NET
Core的不同版本,因此很多示例项目并不是能很容易的运行起来。所以我决定写一篇针对RC2这个版本的.NET
Core入门文章并提供一些能直接运行的示例项目。

QQ截图20190619164332.png (上传于2019-06-22
20:40:20)
澳门新葡亰 1

下载安装 .NET Core SDK

从 dotnet cli github项目主页找到最新版的.Net Core SDK下载:

例如 Mac OS X的最新版的.NET Core SDK的下载地址为:

安装前请确认当前系统是否已经安装了老版本的.NET Core,
如果已经安装,请先卸载。

如在Mac OS X上已安装的话,请运行如下命令删除:

sudo rm -rf /usr/local/share/dotnet

在Mac OS X上安装之前请先确保 openssl 已经被安装了:

brew install openssl

我在上篇博客狠狠的吐槽了这个设计
https://blog.bccn.net/静夜思/66713
,不解决掉这个问题终日寝食难安。

开发工具 Visual Studio Code 及其 C# 插件安装

如不准备使用VSCode进行开发的话,请忽略此部分。我不确定最新版本的 Visual
Studio 2015 Update 2 是否对.NET Core 1.0 RC2有很好的支持。

  1. 从官方网站下载安装 VSCode

  2. 安装VSCode C#插件

    由于支持 RC2 的 C# 插件 v1.0 还未正式发布到 VS Code extension
    仓库里, 因此你只能手动从github下载并安装:

    Mac OS X 下通过 VSCode 打开下载下来的文件即可。

    等到 VS Code C# 插件 v1.0
    版本正式发布了,你就可以通过VSCode的命令窗口来安装 C#
    支持了。详细操作如下:

    运行VSCode, 然后使用快捷键 ⌘ + P
    启动快速打开命令窗口,然后输入如下命令安装C#扩展。最新版的csharp扩展已支持
    RC2 的.NET程序的调试。

    ext install csharp
    

苍天有眼,今天让我搜到一个10年前的帖子
澳门新葡亰,
10年前就有人受这个困扰(然而官僚化的微软始终听不到用户的声音),并且开发了一个扩展,当然这个扩展现在已经不能用了。好在给了我一个启发。

使用.NET CLI (dotnet) 创建,编译和运行项目

  1. 创建项目

首先在控制台/Terminal下进入你要创建项目的目录,然后运行如下命令:

    dotnet new

dotnet cli
创建新项目的时候支持项目类型参数-t,但当前只支持Console参数。:(

运行之后会生成两个文件

    project.json    -   类似于.NET Framework里的项目文件
    Program.cs      -   程序启动入口

使用restore命令下载依赖

    dotnet restore

如出现网络错误导致restore失败的情况请重试几次,貌似这种情况比较少。

如发现类似下面的Warning也请不要惊慌,这是由于CLI的版本号与下载下来的.NET
Core类库的版本号不一致导致的,这种情况不会影响编译和运行。

    warn : Dependency specified was Microsoft.NETCore.App (>= 1.0.0-rc2-3002464) but ended up with Microsoft.NETCore.App 1.0.0-rc2-3002468.
  1. 编译项目

在控制台或Terminal打开项目所在目录,运行如下命令编译:

    dotnet build

如出现如下类似编译错误:

   error NU1002: The dependency Microsoft.CodeAnalysis.Common 1.2.0-beta1-20160202-02 does not support framework .NETCoreApp,Version=v1.0
   error NU1002: The dependency Microsoft.CodeAnalysis.CSharp 1.2.0-beta1-20160202-02 does not support framework .NETCoreApp,Version=v1.0

出现这个问题的可能原因是NuGet上通过版本号匹配到的依赖包并不能使用,你需要做如下操作之后再重新restore一下。

a. 在项目根目录新增文件 NuGet.config, 并写入以下内容:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <packageSources>
            <!--To inherit the global NuGet package sources remove the <clear/>line below -->
            <clear/>
            <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json"/>
            <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json"/>
        </packageSources>
    </configuration>

b. 打开 project.json 文件将 dependencies 节点中的 Microsoft.NETCore.App
的版本好更改为 1.0.0-rc2-*:

    "dependencies": {
        "Microsoft.NETCore.App": {
            "type": "platform",
            "version": "1.0.0-rc2-*"
        }
    }

c. 然后再重新运行 dotnet restore 之后编译

  1. 运行项目

    在控制台或Terminal打开项目所在目录,运行如下命令运行:

    dotnet run
    

    如遇如下错误,

    Expected to load libhostpolicy.dylib from [/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.0-rc2-3002468]
    This may be because the targeted framework ["Microsoft.NETCore.App": "1.0.0-rc2-3002468"] was not found.
    

    也不要慌张,到目录 bin/Debug/netcoreapp1.0中 找到文件
    *.runtimeconfig.json, 将其中 runtime 版本号修改为与本机 CLI
    版本号一致即可。

    {
        "runtimeOptions": {
            "framework": {
                "name": "Microsoft.NETCore.App",
                "version": "1.0.0-rc2-3002485"
            }
        }
    }
    

    如本机 dotnet –version 命令返回值为 “1.0.0-rc2-002485”,则应runtime
    config中的版本号应替换为“1.0.0-rc2-3002485”。

    然后再尝试运行 dotnet run

  2. 调试项目 (Visual Studio Code)

    使用 VSCode 打开项目所在文件夹之后,VSCode
    会问你是否添加启用项目调试相关的文件,你选OK之后目录下会新增文件夹“.vscode”,其中会包含两个文件:

    launch.json
    tasks.json
    

    当你发现无法调试失败的时候,你可以到 launch.json
    文件,检查启动所指向的文件是否正确:

    {
        "name": ".NET Core Launch (console)",
        ...
        "program": "${workspaceRoot}/bin/Debug/netcoreapp1.0/netcore.dll",
        ...
    }
    

于是我开始搜vs的扩展,联机搜“tooltips”关键字的时候搜到一个叫“Tame Visual Studio Editor
Tooltips
”的扩展,看上去像是关于编辑器Tooltips的,仔细看了一下介绍,果然是解决这个问题的。点击download安装即可。扩展详细介绍:

使用 .NET Core 进行 ASP.NET MVC 开发

虽然 dotnet cli 并没有提供直接创建
web/mvc项目的选项,但是我们还是可以手动来创建 mvc 项目的。

  1. 首先是更新 project.json 来支持 mvc:

    {
        "version": "1.0.0-*",
        "content": [
            "wwwroot",
            "Views"
        ],
        "compilationOptions": {
            "preserveCompilationContext": true,
            "emitEntryPoint": true,
            "debugType": "portable"
        },
        "dependencies": {
            "Microsoft.AspNetCore.Diagnostics": "1.0.0-*",
            "Microsoft.AspNetCore.Mvc": "1.0.0-*",
            "Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-*",
            "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*",
            "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*",
            "Microsoft.AspNetCore.StaticFiles": "1.0.0-*",
            "Microsoft.Extensions.Logging.Console": "1.0.0-*",
            "Microsoft.NETCore.App": {
                "type": "platform",
                "version": "1.0.0-rc2-*"
            }
        },
        "frameworks": {
            "netcoreapp1.0": {
            "imports": [
                "portable-net45+wp80+win8+wpa81+dnxcore50"
            ]
            }
        },
        "tools": {
            "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
            "version": "1.0.0-*",
            "imports": "portable-net45+wp80+win8+wpa81+dnxcore50"
            }
        },
        "scripts": {
            "postpublish": "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%"
        }
    }
    
  2. 在NuGet.config 文件中增加 ASP.NET
    的包的下载地址,如此文件不存在请先添加:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <packageSources>
            <!--To inherit the global NuGet package sources remove the <clear/> line below -->
            <clear />
            <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
            <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
            <add key="AspNetCI" value="https://www.myget.org/F/aspnetcirelease/api/v3/index.json" />
        </packageSources>
    </configuration>
    
  3. 增加 Startup.cs 文件 然后在 Program.cs 增加启动代码:

    Startup.cs

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    
    namespace HelloMvc
    {
        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                // 注册MVC相关服务到ASP.NET Core的反转控制器
                services.AddMvc();
            }
    
            public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
            {
                loggerFactory.AddConsole(LogLevel.Debug);
    
                //启用静态文件支持
                app.UseStaticFiles();
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                // 启用 Mvc 并定义默认的路由
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }
    

    Program.cs

    using System;
    using System.IO;
    using Microsoft.AspNetCore.Hosting;
    
    namespace HelloMvc
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var host = new WebHostBuilder()
                            .UseKestrel()
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseDefaultHostingConfiguration(args)
                            .UseIISIntegration()
                            .UseStartup<Startup>()
                            .Build();
    
                host.Run();
            }
        }
    }
    
  4. MVC 其它

    ASP.NET Core中 MVC 具体的开发方法,请参考官方文档

    来学习使用,我在这里就不再累述了。
    完整示例可参考我在github上的示例项目:

    MVC项目也可通过 dotnet run 命令运行,还可以使用VSCode进行调试。

然而我高兴的还是太早了。这个扩展只支持了C#语言,VB.NET根本不如作者的法眼。好在这个扩展是开源的,顺着扩展的介绍页面找到了他的github页面

(可怜目前为止只有2个star,1个fork,其中一个star是我点的,唯一的fork也是我拉了个分支,可见微软的技术在开源社区是何等的冷清),通过阅读
TameVisualStudioEditorToolTips/TameQuickInfo.cs
的代码发现没有对vb.net的支持,这是15、16、17行的代码:

在 .NET Core 中使用 EntityFramework + Sqlite

.NET Core 中的 EntityFramework 也在 RC2 也有较大的变化。包的名字从
“EntityFramework.” 变化为 “Microsoft.EntityFrameworkCore.“。
如需使用Sqlite的话,project.json的包依赖应该为:

"dependencies": {
    ...
    ...
    "Microsoft.EntityFrameworkCore": "1.0.0-*",
    "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0-*",
    "Microsoft.NETCore.App": {
        "type": "platform",
        "version": "1.0.0-rc2-*"
    }
}

另外,frameworks 节点对 netcoreapp1.0 也需增加新的imports
(portable-net45+win8+wp8+wpa81 和 portable-net45+win8+wp8):

"frameworks": {
    "netcoreapp1.0": {
        "imports": [
            "portable-net45+wp80+win8+wpa81+dnxcore50",
            "portable-net45+win8+wp8+wpa81",
            "portable-net45+win8+wp8"
        ]
    }
}

然后在Startup.cs中注册EF相关的服务和DbContext:

public void ConfigureServices(IServiceCollection services)
{
    services.AddEntityFramework()
            .AddEntityFrameworkSqlite()
            .AddDbContext<WebsiteDbContext>(
                options => options.UseSqlite("Data Source=./mvcefsample.sqlite")); //设置链接字符串

    services.AddMvc();
}

再到Configure里面初始化数据库或者启用DbMigration:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        ...

        using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var db = serviceScope.ServiceProvider.GetService<WebsiteDbContext>();

            // do db migrate automatically
            // db.Database.Migrate();

            if (db.Database.EnsureCreated())
            {
                for (int i = 0; i < 10; i++)
                {
                    var article = new Article {
                        Title = string.Format("Article {0}",  i + 1),
                        Content = string.Format("Article {0} content blabla blabla",  i + 1),
                        CreatedTime = DateTime.Now,
                        UpdatedTime = DateTime.Now
                    };

                    db.Articles.Add(article);
                }
                db.SaveChanges();
            }
        }
    }

完整示例可参考我在github上的示例项目:

网站地图xml地图