最近在跟着《Pro ASP.NET Core 3》这本书复习一下相关技术,因为之前看过一遍这本书的上一个版本,当时是《Pro ASP.NET Core 2》,练习过程中就直接使用Visual Studio Code作为开发工具了。

   总体感受用下来,跟宇宙第一编辑器Visual Studio相比,Visual Studio Code的缺点还是很多的。

  • Visual Studio Code在自动化方面,比如创建项目模板,脚手架代码的功能基本没有,需要自己手动从头开始写代码。类似一个高级一些的记事本;
  • 在代码智能感知提示,重构,单元测试方面跟Visual Studio相比,还是弱很多;
  • 在代码的静态编译,拼写错误提示方面基本没有,需要等到编译时才能发现。
  • 大部分都需要手动写代码和手动进行测试,连项目之间的相互引用关系,也需要通过敲命令来实现。

    但相比Visual Studio,Visual Studio Code也有一些优点。

  • Visual Studio Code显的要轻便很多,占用内存和运行速度相比Visual Studio要快很多,软件更新迭代也很快,安装也很快。Visual Studio就很笨重,占用内存大,项目一大,编译和运行起来很慢。当然这也可能是由于第三方比如ReSharper或者代码静态分析慢,总之就是很笨重,这一点,今天发布了第一款64位的Visual Studio,不知道能否解决慢的问题。
  • Visual Studio Code在扩展性方面要强不少,大部分的功能都是通过插件来实现的,连C#编辑器也是一个插件,可以很容易用来编写其他语言的代码,比如python,go,markdown等等,这只是安装一个插件的事情。
  • Visual Studio Code在某些功能,比如对yml文件的拼写检查支持,要比Visual Studio强。
  • Visual Studio Code免费,且跨平台,意味着你可以在其他平台比如Ubuntu,MacOS上也可以拿来写代码。

    这里记录一下,我在使用Visual Studio Code方面的一些实践操作,熟悉之后,基本上可以取代Visual Studio用来开发ASP.NET Core项目了,但是如果实在Windows平台上如果有条件使用Visual Studio,单独上面的静态编译检查,那个效率应该是要更高一些的。

快捷键


    在使用编辑器的时候,最常用的是快捷键,这里列举几个常用的快捷键。

  • Ctrl+K+S,打开快捷键设置界面,界面如下,可以在这里统一设置快捷键。
  • Shift+Alt+F,代码格式化,包括自动调整缩进,层级等,F可以记作Format。
  • Ctrl+K+C,注释代码,C可以记作Cancel
  • Ctrl+K+U,取消代码注释,U可以记为Undo
  • Ctrl+Shift+P,显示所有快捷命令,P可以记为Package,当安装完各种插件之后,都可以在这里显示,选择之后可以进行后续操作。

插件


   当你安装完Visual Studio Code的时候,基本是个空壳子,里面的很多功能需要通过插件来实现和扩展,比如要编写C#代码,就需要安装C#插件来提供编辑器支持。插件的安装在Visual Studio Code里面也很容易,跟在Visual Studio里面安装NuGet包一样,安装起来也很简单,直接在输入框里搜索需要安装的插件,然后选中之后,在右边会显示该插件的功能,用法等等。如下图:

我这里安装了一些插件,供参考:

  • C#插件,用来提供C#运行时环境。
  • Docker插件,用来提供Docker运行和调试环境
  • Kubernetes插件,容易编排会用到。
  • LibMan Tools插件,用来管理第三方静态资源包,比如bootstrap,fontaware包等等。
  • NugGet Package Manager插件,用来安装NugGet包。
  • YAML插件,YAML文件编辑支持,在docker获kubernetes里面都会用到YAML文件。
  • Markdown All in One插件,用来直接编写和预览Markdown文档
  • Markdown Preview Github Styling插件,Github风格的Markdown预览
  • HTML CSS Support插件,CSS样式表支持。

新建工程项目


    在Visual Studio Code里面,没有类似Visual Studio里面的Wizard向导帮助我们创建项目以及基本的脚手架文件,在Visual Studio Code里一切都需要靠敲命令来完成。

    在进行新建工程之前,我们需要新建一个文件夹,用来存放我们的所有项目,比如我这里新建一个D:\Study\ASPNETCORESTUDY的文件夹。然后打开Visual Studio Code里面的Terminal,他其实在内部是一个嵌入的Windows PowerShell,直接打开Windows PowerShell也可以操作。

    然后使用dotnet相关命令,创建项目和工程。使用dotnet new命令,可以列出来所有提供的“模板”,这个有点类似Visual Studio里面的新建项目Wizard向导,但比那个要简陋,而且需要通过命令来实现。

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

PS D:\Study\ASPNETCORESTUDY> dotnet new
模板名                                           短名称                  语言          标记
--------------------------------------------  -------------------  ----------  ----------------------
Console Application                           console              [C#],F#,VB  Common/Console        
Class library                                 classlib             [C#],F#,VB  Common/Library        
WPF Application                               wpf                  [C#],VB     Common/WPF
WPF Class library                             wpflib               [C#],VB     Common/WPF
WPF Custom Control Library                    wpfcustomcontrollib  [C#],VB     Common/WPF
WPF User Control Library                      wpfusercontrollib    [C#],VB     Common/WPF
Windows Forms App                             winforms             [C#],VB     Common/WinForms       
Windows Forms Control Library                 winformscontrollib   [C#],VB     Common/WinForms       
Windows Forms Class Library                   winformslib          [C#],VB     Common/WinForms       
Worker Service                                worker               [C#],F#     Common/Worker/Web     
Unit Test Project                             mstest               [C#],F#,VB  Test/MSTest
NUnit 3 Test Project                          nunit                [C#],F#,VB  Test/NUnit
NUnit 3 Test Item                             nunit-test           [C#],F#,VB  Test/NUnit
xUnit Test Project                            xunit                [C#],F#,VB  Test/xUnit
Razor Component                               razorcomponent       [C#]        Web/ASP.NET
Razor Page                                    page                 [C#]        Web/ASP.NET
MVC ViewImports                               viewimports          [C#]        Web/ASP.NET
MVC ViewStart                                 viewstart            [C#]        Web/ASP.NET
Blazor Server App                             blazorserver         [C#]        Web/Blazor
Blazor WebAssembly App                        blazorwasm           [C#]        Web/Blazor/WebAssembly
ASP.NET Core Empty                            web                  [C#],F#     Web/Empty
ASP.NET Core Web App (Model-View-Controller)  mvc                  [C#],F#     Web/MVC
ASP.NET Core Web App                          webapp               [C#]        Web/MVC/Razor Pages
ASP.NET Core with Angular                     angular              [C#]        Web/MVC/SPA
ASP.NET Core with React.js                    react                [C#]        Web/MVC/SPA
ASP.NET Core with React.js and Redux          reactredux           [C#]        Web/MVC/SPA
Razor Class Library                           razorclasslib        [C#]        Web/Razor/Library
ASP.NET Core Web API                          webapi               [C#],F#     Web/WebAPI
ASP.NET Core gRPC Service                     grpc                 [C#]        Web/gRPC
dotnet gitignore file                         gitignore                        Config
global.json file                              globaljson                       Config
NuGet Config                                  nugetconfig                      Config
Dotnet local tool manifest file               tool-manifest                    Config
Web Config                                    webconfig                        Config
Solution File                                 sln                              Solution
Protocol Buffer File                          proto                            Web/gRPC

Examples:
    dotnet new mvc --auth Individual
    dotnet new reactredux
    dotnet new --help
    dotnet new nunit --help

    可以看到,有许多项目我们可以直接通过使用dotnet new来创建,需要说明的时候,我们在创建项目的时候,需要指定输出文件夹,这个文件夹名称,默认就是项目文件的名称。现在我们来创建一个配置文件、一个web项目、一个工程文件、并将项目文件加入到工程文件里来。

//创建globaljson配置文件,指定.net sdk版本,以及文件存放目录,这里使用的是.NET 5.0,存放在SportsSln文件夹下的SportsStore目录下
dotnet new globaljson --sdk-version 5.0 --output SportsSln/SportsStore
//创建web项目,项目不需要支持https,项目的存放位置为SportsSln文件夹下的SportsStore目录,项目的框架使用的是.net5.0
dotnet new web --no-https --output SportsSln/SportsStore --framework net5.0
//创建一个SportsSln.sln工程文件文件
dotnet new sln -o SportsSln
//将项目文件SportsSln/SportsStore.csprj加入到SportsSln.sln工程文件中来
dotnet sln SportsSln add SportsSln/SportsStore

添加单元测试测试项目


   我们可以在创建一个针对上述web项目的测试项目,同样,需要通过命令来进行,可以看到,同创建web项目一样,需要通过命令新建测试项目,引用被测试项目,将项目添加到成功文件中等等操作。

//添加xunit测试项目,输出目录为SportsSln/SportsStore.Tests,默认的项目名称为SportsStore.Tests
dotnet new xunit -o SportsSln/SportsStore.Tests --framework net5.0
//测试上述新建的xunit测试项目添加到SportsSln.sln工程文件中
dotnet sln SportsSln add SportsSln/SportsStore.Tests
//为了进行测试,需要将web项目添加到测试项目中来
dotnet add SportsSln/SportsStore.Tests reference SportsSln/SportsStore
//为测试项目添加Moq包
dotnet add SportsSln/SportsStore.Tests package Moq --version 4.16.1
//删除默认的创建的测试文件
Remove-Item SportsStore.Tests/UnitTest1.cs
//运行测试
dotnet test 

     完成之后就可以编写测试了,编写完成之后,可以使用测试用例上方的智能提示来直接运行测试。

  • Run/Debug AllTest,可以运行/调试所有测试用例。
  • Run/Debug Test,可以运行/调试当前测试用例。
  • 在下方的output中,可以看到运行测试后的输出结果。

    有时候,会碰到这些提示出不来的情况,可以重启一下Visual Studio Code,或者直接切换到测试项目目录下,运行dotnet test。

添加第三方包和工具


    上面介绍了项目之间的引用,可以通过dotnet add a reference b来实现a项目引用b项目的功能,有时候,我们需要引用第三方的NuGet Package包。在Visual Studio Code中,提供了NuGet Package包管理插件,可以通过向导式的一步一步来引导我们添加对应的包。

     如果通过NuGet Package来添加包,可以通过Ctrl+Shift+P,打开快捷命令,然后选择NuGet Package Manager:Add Package:

    然后接下,在输入框中,输入我们要添加的包,这里我们添加EntityFrameworkCore需要的包为例,在接下来的输入框中,我们输入EntityFrameworkCore,可以看到有许多匹配的相关包,我们这里选择Microsoft.EntityFrameworkCore,然后在下一步会弹出所有的版本,选中相关版本即可添加:

   它在本质上,是帮我们向导式的在项目文件.csproj中,往ItemGroup中添加相关的包引用。完成之后,还需要执行dotnet restore,来恢复相关的包引用。

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.6"/>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.6"/>
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.6"/>
  </ItemGroup>
</Project>

   除了通过以上方式,还可以直接通过dotnet add package 命令来添加相关的包引用,通过命令方式添加的包,不需要进行restore。

dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 5.0.6 
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore --version 5.0.6

dotnet add SimpleApp.Tests package Moq --version 4.16.1

   删除安装包,可以使用dotnte remove package命令。

dotnet remove package Microsoft.EntityFrameworkCore.SqlServer

   完了之后,还可以通过dotnet list package命令查看所有安装的包。

PS D:\Study\ASPNETCORESTUDY\SportsSln> dotnet list package
项目“SportsStore”具有以下包引用
   [net5.0]:
   顶级包                                                      已请求     已解决
   > Microsoft.AspNetCore.Identity.EntityFrameworkCore      5.0.6   5.0.6
   > Microsoft.EntityFrameworkCore.Design                   5.0.6   5.0.6
   > Microsoft.EntityFrameworkCore.SqlServer                5.0.6   5.0.6

项目“SportsStore.Tests”具有以下包引用
   [net5.0]:
   顶级包                              已请求      已解决
   > coverlet.collector             1.3.0    1.3.0
   > Microsoft.NET.Test.Sdk         16.7.1   16.7.1
   > Moq                            4.16.1   4.16.1
   > xunit                          2.4.1    2.4.1
   > xunit.runner.visualstudio      2.4.3    2.4.3

安装EF,LibMan等工具


    除了安装包之外,有时候,还需要安装一些其他常用的工具,比如EntityFramework迁移工具,LibMan包管理工具,私密文件管理工具等,这些都可以通过dotnet tool来完成。

    安装EntityFramework迁移工具:

//首先移除dotnet-ef包 Entity Framework Core .NET Command-line Tools 5.0.0
dotnet tool uninstall --global dotnet-ef
//安装dotnet-ef包 --global表示不仅在该项目使用
dotnet tool install --global dotnet-ef --version 5.0.6
//查看帮助
dotnet ef --help

   相关ef迁移命令:

dotnet ef migrations add Initial
dotnet ef migrations remove //撤销

dotnet ef migrations add Initial --context AppIdentityDbContext
dotnet ef database update --context AppIdentityDbContext
dotnet ef database drop --force --context AppIdentityDbContext

dotnet ef database drop --force --context StoreDbContext
dotnet ef database update --context StoreDbContext

    安装LibManager客户端js库管理工具:

dotnet tool uninstall --global Microsoft.Web.LibraryManager.Cli
//如果不指定版本,则安装最新的版本
dotnet tool install --global Microsoft.Web.LibraryManager.Cli
//也可以指定版本
dotnet tool install --global Microsoft.Web.LibraryManager.Cli --version 2.0.96

    LibMan相关命令:

//初始化创建一个libman.json文件,并使用cdnjs作为provider源
libman init -p cdnjs
//安装js包:
libman install twitter-bootstrap -d wwwroot/lib/twitter-bootstrap
libman install twitter-bootstrap@4.3.1 -d wwwroot/lib/twitter-bootstrap
libman install font-awesome@5.12.0 -d wwwroot/lib/font-awesome

   这个也可以通过LibMan插件来安装脚本,方法类似上面添加包的方式,使用快捷键Ctrl+Shift+P,这个只能初始化libman.json文件,添加包还是需要通过命令行来进行。

安装本地加密配置工具:

dotnet tool uninstall --global dotnet-user-secrets
dotnet tool install --global dotnet-user-secrets 

    user-secrets相关命令:

//初始化
dotnet user-secrets init
//写入待私有值
dotnet user-secrets set "WebService:Id" "MyAccount"
dotnet user-secrets set "WebService:Key" "MySecret123$"
//列出所有配置的值
dotnet user-secrets list

    user-secrets实际上是将一部分配置文件,存储到本地,而不是代码中。在init初始化的时候,在项目文件中添加了一个UserSecretsId:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <UserSecretsId>6ff9a541-c314-41d3-93b4-51ddebf277ad</UserSecretsId>
  </PropertyGroup>
</Project>

    然后,在本机的相关目录下 %APPDATA%\Microsoft\UserSecrets ,即可找到对应的json文件。

    secrets.json内容如下:

{
  "WebService:Id": "MyAccount",
  "WebService:Key": "MySecret123$"
}

调试和运行


    编码完成之后,可以使用dotnet相关命令进行编译运行:

//恢复
dotnet restore
//编译
dotnet build
//运行
dotnet run

    上述不方便调试,可以使用Run菜单下的Debug命令,或者直接按F5来执行调试。

    如果是初次调试,可能需要编辑.vscode下面的launch.json文件,将项目的相关配置添加进来。这样,才能直接在界面上显示和使用。