搭建简单的.net core mvc开发工程

难度:简单
类型:step-by-step
适用:初学者
SDK:.NET Core SDK 1.1.1
编辑器:Visual Studio Code 1.1.1
关键词:.net core, mvc, solution, xunit
笔者环境:macOS

一. 环境准备:

1.1 sdk下载安装:

下载地址:https://www.microsoft.com/net/core
根据系统选择下载并安装。
运行命令查看安装是否成功:

>> dotnet --version
1.1.1

成功显示版本号,证明安装成功。

1.2 VSCode下载安装:

下载地址:https://code.visualstudio.com/
安装必要扩展:C#、C# Extensions、Asp.NET Helper

Visaul Studio Code

二. 工程搭建

2.1 新建解决方案

  1. 新建并打开文件夹
打开文件夹
  1. 使用快捷键 Ctrl + ' 唤出命令行:

    打开命令行

  2. 在命令行输入命令,创建solution:

>> dotnet new sln
Content generation time: 242.8175 ms
The template "Solution File" created successfully.
创建solution

2.2 创建web项目

  1. 命令行创建项目文件夹并进入:
>> mkdir web && cd web
  1. 创建mvc项目:
>> dotnet new mvc
The template "ASP.NET Core Web App" created successfully.
创建mvc项目
  1. 退到根目录并添加sln引用:
>> cd .. && dotnet sln add web/web.csproj
Project `web/web.csproj` added to the solution.
  1. 选择环境:按F5选择.net core环境
  2. 编辑启动项:
  • 打开.vscode/launch.json文件
  • 找到"name": ".NET Core Launch (web)",节点
  • 编辑program字段
"program": "${workspaceRoot}/bin/Debug/<target-framework>/<project-name.dll>",

改为:

"program": "${workspaceRoot}/bin/Debug/netcoreapp1.1/web.dll",
  • 编辑cwd字段:
"cwd": "${workspaceRoot}",

改为:

"cwd": "${workspaceRoot}/web/",
  1. 编辑启动任务:
  • 打开.vscode/task.json文件
  • 编辑tasksargs字段:
"args": [""]

改为:

"args": ["${workspaceRoot}/web/web.csproj"]
  1. 测试运行:
  • F5运行项目,可以看到控制台打印出如下信息:
Microsoft (R) Build Engine version 15.1.548.43366
Copyright (C) Microsoft Corporation. All rights reserved.
  web -> ~/dotnetcore_mvc_example/web/bin/Debug/netcoreapp1.1/web.dll
Build succeeded.
    0 Warning(s)
    0 Error(s)
Time Elapsed 00:00:03.30
默认页面
  1. 修改启动端口:
    .netcore mvc默认启动端口是5000,需要其他端口可以自行修改。
  • 打开Program.cs文件
  • WebHostBuilder中增加UserUrls配置,例如改为8088:
      public static void Main(string[] args)
      {
          var host = new WebHostBuilder()
              .UseKestrel()
              .UseContentRoot(Directory.GetCurrentDirectory())
              .UseIISIntegration()
              .UseStartup<Startup>()
              .UseUrls("http://localhost:8088")
              .Build();

          host.Run();
      }
  1. 至此mvc项目初始化完毕。

2.3 创建data-service-model等项目

  1. 在项目根目录一次创建目录
>> mkdir datas && mkdir services && mkdir models
  1. 初始化类库项目:
>> cd datas && dotnet new classlib
The template "Class library" created successfully.
>> cd ../services && dotnet new classlib
The template "Class library" created successfully.
>> cd ../models && dotnet new classlib
The template "Class library" created successfully.
项目结构
  1. 修改.netstandard版本号:
    目前创建项目,默认类库使用netstandard1.4,需要修改为最新的1.6
  • 打开xxx.csproj
<TargetFramework>netstandard1.4</TargetFramework>

改为:

<TargetFramework>netstandard1.6</TargetFramework>
  1. 把项目添加到sln:
    命令与web项目一样,添加到sln中:
>> dotnet sln add datas/datas.csproj
Project `datas/datas.csproj` added to the solution.
>> dotnet sln add services/services.csproj
Project `services/services.csproj` added to the solution.
>> dotnet sln add models/models.csproj
Project `models/models.csproj` added to the solution.
  1. 添加项目之间的引用:
  • web引用servicesmodels

dotnet add web/web.csproj reference models/models.csproj
Reference ..\models\models.csproj added to the project.
dotnet add web/web.csproj reference services/services.csproj
Reference ..\services\services.csproj added to the project.
```
查看web.csproj,可以看到引用添加如下:

  <ItemGroup>
    <ProjectReference Include="..\models\models.csproj" />
    <ProjectReference Include="..\services\services.csproj" />
  </ItemGroup>
  • 添加services引用datasmodels
  <ItemGroup>
    <ProjectReference Include="..\models\models.csproj" />
    <ProjectReference Include="..\datas\datas.csproj" />
  </ItemGroup>

三. 完整示例

3.1 使用dapper

  1. datas项目添加dapper的引用:
>> dotnet add datas/datascsproj package dapper
Microsoft (R) Build Engine version 15.1.548.43366
Copyright (C) Microsoft Corporation. All rights reserved.
  ...
info : PackageReference for package 'dapper' version '1.50.2' added to file '~/dotnetc
ore_mvc_example/datas/datas.csproj'.

.net core 会自动下载引用nuget中的项目

  <ItemGroup>
        <PackageReference Include="dapper" Version="1.50.2" />
  </ItemGroup>
  1. 配置数据库连接字符串
    • 打开web/appsettings.json添加ConnectionStrings字段,假定数据库为读写分离:
  "ConnectionStrings": {
    "read": "your read database connection string",
    "write": "your write database connection string"
  }
  1. 编写Repository.cs
    • datas项目添加Microsoft.Extensions.Configuration的依赖
  <ItemGroup>
    <PackageReference Include="dapper" Version="1.50.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.1" />
  </ItemGroup>
- 假定数据库中含有表`Greeting`,表字段为`Id`和`Greetings`,创建Greeting的ORM对象:
示例数据.png
    public class Greeting
    {
        public int Id { get; set; }
        public string Greetings { get; set; }
    }
- 读取配置中的数据库连接字符串,并且使用Dapper查询:
    public class Repository
    { 
        //注入IConfigurationRoot
        public Repository(IConfigurationRoot configuration)
        {
            _configuration = configuration;
        }
        private IConfigurationRoot _configuration { get; }
        private string _readConnStr => _configuration.GetConnectionString("read");
        private string _writeConnStr => _configuration.GetConnectionString("write");
        //通过id查询第一条记录并返回entity
        public virtual Greeting GetGreeting(int id)
        {
            string sql = "SELECT Id,Greetings FROM Greeting WHERE Id=@id";
            using (var conn = new SqlConnection(_readConnStr))
            {
                return conn.QueryFirst<Greeting>(sql, new { id });
            }
        }
    }

3.2 编写model和service

  1. models项目中创建GreetingModel.cs
namespace models
{
    public class GreetingModel
    {
        public string Greetings { get; set; }
    }
}
  1. services项目中创建GreetingService.cs
namespace services
{
    public class GreetingService
    {
        private Repository _repository;
        //注入repository
        public GreetingService(Repository repository)
        {
            _repository = repository;
        }
        public virtual GreetingModel GetGreetings(string name = "")
        {
            var data = _repository.GetGreeting(1);
            return new GreetingModel()
            {
                Greetings = $"{data.Greetings} {name}!"
            };
        }
    }
}

3.3 创建controller

  1. web项中创建Controllers/GreetingController.cs
namespace web.Controllers
{
    public class GreetingController : Controller
    {
        private GreetingService _service;
        //注入service
        public GreetingController(GreetingService service)
        {
            _service = service;
        }
        //通过service获取model
        public JsonResult Index(string name = "")
        {
            var model = _service.GetGreetings(name);
            return Json(model);
        }
    }
}

3.4 添加依赖注入

  1. 打开web项目的Startup.cs
  2. ConfigureServices.cs添加依赖注入:
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();
            //添加IConfigurationRoot的单例的依赖注入
            services.AddSingleton(provider => Configuration);
            //添加Repository的依赖注入
            services.AddTransient<Repository>();
            //添加GreetingService的依赖注入
            services.AddScoped<GreetingService>();
        }

3.5 运行

  1. 直接 F5运行项目,如果遇到问题可以使用命令restore后在运行
>> dotnet restore && dotnet build
  1. 启动后,可以打开地址:http://localhost:8088/greeting/?name=world 进行查看。运行正确会显示如下json:
{"greetings":"Hello world!"}

四. 单元测试

4.1 创建测试项目

  1. 创建目录tests并进入
  2. 初始化xunit单元测试项目
>> dotnet new xunit
Content generation time: 275.91 ms
The template "xUnit Test Project" created successfully.
  1. 添加工程内项目依赖,和Moq依赖
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
    <PackageReference Include="xunit" Version="2.2.0" />
    <PackageReference Include="moq" Version="4.7.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\services\services.csproj" />
    <ProjectReference Include="..\datas\datas.csproj" />
    <ProjectReference Include="..\web\web.csproj" />
  </ItemGroup>

4.2 编写测试类和方法

  1. 创建GreetingServiceUnitTest.cs测试类
    public class GreetingServiceUnitTest
    {
        [Fact]
        public void TestGreetingService()
        {
            //moq相关依赖,并且执行service方法得到结果
            var config = new Mock<IConfigurationRoot>();
            var repository = new Mock<Repository>(config.Object);
            repository.Setup(p=>p.GetGreeting(1)).Returns(MoqGreetingData());

            var service = new GreetingService(repository.Object);
            var result =  service.GetGreetings("world"); 

            Assert.NotNull(result);
            
            Assert.Equal(result.Greetings, "hello world!");
        }

        private Greeting MoqGreetingData()
        {
            return new Greeting() { Greetings = $"hello" };
        }
    }

4.3 执行测试

执行dotnet test命令:

>> dotnet test
Build started, please wait...
Build completed.
Test run for ~/dotnetcore_mvc_example/example_tests/bin/Debug/netcoreapp1.1/example_te
sts.dll(.NETCoreApp,Version=v1.1)
Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.
Starting test execution, please wait...
...
Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 2.7017 Seconds

五. 发布和部署

5.1 发布

  • cdweb项目目录
  • 执行发布命令:
>> dotnet publish
Microsoft (R) Build Engine version 15.1.548.43366
Copyright (C) Microsoft Corporation. All rights reserved.
  models -> ~/dotnetcore_mvc_example/models/bin/Debug/netstandard1.6/models.dll
  datas -> ~/dotnetcore_mvc_example/datas/bin/Debug/netstandard1.6/datas.dll
  services -> ~/dotnetcore_mvc_example/services/bin/Debug/netstandard1.6/services.dll
  web -> ~/dotnetcore_mvc_example/web/bin/Debug/netcoreapp1.1/web.dll
  • 发布成功后,会生成目录~/web/bin/Debug/netcoreapp1.1/publish/

    发布目录

5.2 部署

  1. 准备好生产环境,如安装好.net core sdk的Linux机器
  2. 上传~/publish/目录所有文件到服务器
  3. 服务器上执行运行命令:
>> dotnet web.dll
Hosting environment: Production
Content root path: ~/wwwroot/dotnet_mvc_example/
Now listening on: http://localhost:8088
Application started. Press Ctrl+C to shut down.
  1. 访问测试页面,http://localhost:8088/greeting/?name=world
>> curl http://localhost:8088/greeting/?name=world
{"greetings":"Hello world!"}
  1. 配置Nginx的nginx.conf文件,增加内容:
server {
        listen 80;
        server_name xxx.xxx.com;#你的域名
        location / {
                root html;
                index index.html index.htm;
                proxy_pass http://127.0.0.1:8088;#.net core项目本地地址
                #转发ip地址http头
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
        }

}

重启Nginx,访问域名即可生效

六. 注意事项

  • 添加项目后,需要添加到sln,否则项目无法正常使用
  • 添加引用后,需要dotnet restore否则编码时无自动提示

七. 示例源码:

https://github.com/mcjiffy/dotnetcore_mvc_example

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,757评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,478评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,540评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,593评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,903评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,329评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,659评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,383评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,055评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,337评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,864评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,227评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,820评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,999评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,750评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,365评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,260评论 2 258

推荐阅读更多精彩内容