作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Zablon Dawit的头像

Zablon Dawit

Zablon是一个专注于ASP的全栈web开发人员.。NET和JavaScript. 他曾为多家公司开发企业软件,包括Pelmorex Corp .和S.R.E软件开发.

工作经验

5

Share

Developing .. NET解决方案 Linux 一直是一个挑战,因为微软的Visual Studio需要Windows才能工作. 在研究了几个 .NET 项目中,我决定测试一下开发的极限 .NET on Linux. 这个简单的教程主要介绍一个 ASP.NET MVC 应用程序与SQL Server显示如何优雅和有效 .NET development 能在我喜欢的操作系统上运行吗.

开发环境

首先,我们必须确保 .. NET工具和SDK与 Linux的特殊风格 安装时使用 微软的标准指南.

我喜欢的开发环境是由窗口集成开发环境(IDE)组成的。, 一个强大的数据库管理和查询工具, 数据库本身, 以及用于构建和部署的工具. 我使用以下工具来实现可靠的功能并实现美丽的编码体验:

在继续我们的示例应用程序之前,请确保正确安装了这些工具.

项目脚手架

在这个示例应用程序中,我们将突出显示ASP.NET开发和功能通过一系列的用例为一个假想的鞋店库存管理系统. As with any new .. NET应用程序,我们需要创建一个解决方案,然后向其中添加一个项目. 我们可以利用 .. NET SDK CLI工具来支撑我们的新解决方案:

mkdir Shoestore && cd Shoestore
dotnet new sln

Next, create an ASP.NET 为简单起见,包含显式主类的项目, 由于这个项目的结构是最熟悉的 ASP.NET developers. 控件创建项目 MVC pattern:

mkdir Shoestore.mvc && cd Shoestore.mvc
Dotnet新MVC——use-program-main=true

接下来,将项目添加到解决方案中:

#找到解决方案的根源
cd ..
. net添加鞋店.mvc/

我们现在有了一个默认的解决方案,它包含了ASP.NET project. 在继续之前,确保一切都构建好了:

cd Shoestore.mvc/
dotnet restore
dotnet build

良好的开发实践 鼓励将关键服务和应用运行时放入Docker容器中,以改进部署和可移植性. 因此,让我们创建一个简单的Docker容器来支持我们的应用程序.

应用程序的可移植性

Docker镜像通常引用另一个父Docker镜像作为基本需求(如操作系统和基本解决方案)的可接受起点, 包括数据库. 按照这个Docker最佳实践,创建一个 Dockerfile and a Docker Compose 文件以进行正确的服务配置,同时引用microsoft发布的父映像. We’ll use Docker stages 让我们的形象保持小一点. 阶段允许我们使用 .. NET SDK在构建我们的应用程序时使用.只有在应用程序运行时才需要。NET运行时.

Create the Shoestore.mvc Dockerfile,内容如下:

# Shoestore \ Shoestore.mvc\Dockerfile
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR / shoestore
COPY Shoestore.mvc/*.csproj ./
#恢复项目包
运行dotnet恢复
COPY Shoestore.mvc/* ./
创建一个发布版本
运行dotnet build -c Release -o /app/build

#运行应用程序并使其在端口80上可用
FROM mcr.microsoft.com/dotnet/aspnet: 6.0
WORKDIR /app
EXPOSE 80
#资产和视图
COPY Shoestore.mvc/Views ./Views
COPY Shoestore.mvc/wwwroot ./wwwroot
COPY——from=build /app/build ./
入口点["。net", "Shoestore ".mvc.dll" ]

接下来,我们将创建 docker-compose.yml 文件在我们的解决方案的根目录. 最初,它将只包含对应用程序服务的引用 .Dockerfile:

# Shoestore / docker-compose.yml
version: "3.9"
services:
  web:
    build:
      context: .
      dockerfile: Shoestore.mvc/Dockerfile
    ports:
      - "8080:80"

我们还可以用 .dockerignore文件 确保只有构建工件被复制到我们的映像中.

现在我们的应用程序服务已经准备好了,它的执行环境也可以运行了, 我们需要创建数据库服务,并将其连接到Docker配置.

数据库服务

将Microsoft SQL Server添加到Docker配置中是很简单的, 特别是因为我们使用的是微软提供的Docker镜像,而不需要修改它. 的底部添加以下配置块 docker-compose.yml 配置数据库的文件:

  db:
    image: "mcr.microsoft.com/mssql/server”
    environment:
      SA_PASSWORD:“custom_password_123”
      ACCEPT_EULA:“Y”
    ports:
      - "1433:1433"

Here, ACCEPT_EULA 防止安装停止,我们的 ports 设置允许默认的SQL Server端口通过而不进行转换. 这样,我们的Compose文件就包含了应用程序服务和数据库.

在定制应用程序代码之前,让我们验证一下Docker环境是否正常工作:

#从解决方案的根开始
Docker compose up——build

假设启动过程中没有出现错误, 我们不完整的示例应用程序应该可以通过本地地址的web浏览器访问 http://localhost:8080.

代码生成工具

现在我们开始关注有趣的部分:自定义应用程序代码并确保应用程序数据保存在Microsoft SQL Server数据库中. 我们将同时使用 Entity Framework (EF) and .. NET SDK工具将应用程序连接到数据库并支撑应用程序的模型, view, controller, 和ef要求的配置.

在指定所需的工具之前,必须创建一个 tool-manifest file:

#从解决方案的根开始

Dotnet新工具清单

使用以下简单命令将EF和SDK工具添加到该文件中:

Dotnet工具安装Dotnet -ef
Dotnet工具安装Dotnet -aspnet-codegenerator

要验证这些工具的正确安装,请运行 dotnet ef. 如果出现独角兽,说明安装正确. Next, run dotnet aspnet-codegenerator to test the ASP.NET tools; the output should be a general CLI usage block.

现在我们可以使用这些工具来创建应用程序.

MVC: Model

构建应用程序的第一个任务是创建模型. 因为这个模型稍后会添加到数据库中, 我们将在我们的项目中包含MS SQL Server和EF包:

cd Shoestore.mvc/
dotnet添加软件包微软.AspNetCore.Diagnostics.EntityFrameworkCore
dotnet添加软件包微软.EntityFrameworkCore.SqlServer
dotnet添加软件包微软.EntityFrameworkCore.Tools
dotnet restore

Next, 创建EF数据库上下文对象,该对象确定将哪些模型添加到数据库中, 并允许我们的代码轻松地访问和查询数据库中的数据.

Create a Data 目录来存放特定于ef的代码,并创建 ApplicationDBContext.cs 包含以下内容的文件:

/ / Shoestore / Shoestore.mvc /数据/ ApplicationDBContext.cs
using Microsoft.EntityFrameworkCore;

名称空间Shoestore.mvc.Data;

ApplicationDBContext: DbContext
{
  public ApplicationDBContext(DbContextOptions options):base(options){}
}

Next, 配置数据库连接字符串, 哪个必须与我们配置的凭据相匹配 Dockerfile. 的内容 Shoestore / Shoestore.mvc/appsettings.json 致:

{
  "Logging": {
    "LogLevel": {
      “默认”:“信息”,
      "Microsoft.AspNetCore”:“警告”
    }
  },
  “AllowedHosts”:“*”,
  " ConnectionStrings ": {
    :“Shoestore =主服务器=数据库;数据库;用户= sa;密码= custom_password_123;”
  }
}

配置了数据库连接字符串并对数据库上下文进行了编码, 我们已经准备好编写应用程序了 Main function. We’ll include 数据库异常处理 简化系统调试. 另外,因为a .生成代码中的。NET错误导致Docker容器不能正确地服务于我们的视图, 我们需要在视图服务配置中添加特定的代码. 这将显式地将文件路径设置为我们在Docker镜像中的视图位置:

using Microsoft.EntityFrameworkCore;
using Shoestore.mvc.Data;

名称空间Shoestore.mvc;

// ...

    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder (args);
        //关联EF数据库上下文,并将其配置为连接字符串
        var connectionString = builder.Configuration.GetConnectionString(“Shoestore”);
        builder.Services.AddDbContext(
            options => options.UseSqlServer (connectionString));
        //中间件捕获未处理的异常并显示堆栈跟踪
        builder.Services.AddDatabaseDeveloperPageExceptionFilter ();

        //向容器中添加服务.
        // ASP.. NET有一个已知的问题,即最终构建的应用程序不知道视图在哪里
        //文件(在Docker容器中). 
        //修复方法是专门添加视图位置.
        builder.Services
            .AddControllersWithViews ()
            .AddRazorOptions(options => {
                options.ViewLocationFormats.Add("/{1}/{0}.cshtml");
                options.ViewLocationFormats.Add("/Shared/{0}.cshtml");
            });

直接跳到 IsDevelopment if 语句,以便在系统处于开发模式时向系统添加数据库迁移端点. Add an else 语句,代码如下:

        //配置HTTP请求管道.
        if (!app.Environment.IsDevelopment())
        {
            //保留if块的内容. 为了清晰起见,这些都隐藏起来了.
        } else {
            app.UseMigrationsEndPoint ();
        }

接下来,运行一个快速测试以确保新包和源代码编辑正确编译:

//进入mvc目录
cd Shoestore.mvc
dotnet restore
dotnet build

现在,让我们用必需的字段填充模型 Shoestore.mvc\Models\Shoe.cs file:

名称空间Shoestore.mvc.Models;

鞋的公共类
    public int ID { get; set; }
    public string? Name { get; set; }
    public int? Price { get; set; }
    public DateTime CreatedDate { get; set; }
}

EF根据关联的模型、它的上下文文件和应用程序中的任何EF代码生成SQL. 然后根据需要将SQL结果翻译并返回到我们的代码中. If we add our Shoe 模型到我们的数据库上下文, EF将知道如何在MS SQL Server和我们的应用程序之间进行转换. 让我们在数据库上下文文件中做这个, Shoestore / Shoestore.mvc /数据/ ApplicationDBContext.cs:

using Microsoft.EntityFrameworkCore;
using Shoestore.mvc.Models;

名称空间Shoestore.mvc.Data;

ApplicationDBContext: DbContext
{
  public ApplicationDBContext(DbContextOptions options) : base(options) { }

    private DbSet? _shoe { get; set; }
    public DbSet Shoe {
        set => _shoe = value;
        get => _shoe ?? 抛出新的InvalidOperationException("未初始化属性" + nameof(Shoe));
    }
}

最后,我们将使用数据库迁移文件将模型导入数据库. EF工具基于数据库上下文及其相关模型(例如SQL Server)创建特定于MS SQL Server的迁移文件.e., Shoe):

cd Shoestore.mvc/
dotnetef migrations添加InitialCreate

让我们暂时不运行迁移,直到我们有了控制器和视图.

MVC:控制器和视图

我们将使用ASP创建我们的控制器.. NET代码生成工具. 这个工具非常强大,但需要特定的助手类. Use the Design 风格包的基本控制器结构及其EF集成. 让我们添加这些包:

cd Shoestore.mvc\
dotnet添加软件包微软.VisualStudio.Web.CodeGeneration.Design && \
dotnet添加软件包微软.EntityFrameworkCore.Design && \
dotnet restore

现在,创建默认控制器就像调用下面的命令一样简单:

cd Shoestore.mvc\
代码生成器控制器
        -name ShoesController
        -m Shoe \
        -dc ApplicationDBContext
        ——relativeFolderPath Controllers \
        ——useDefaultLayout \
        ——referenceScriptLibraries

当代码生成器创建控制器时,它也会为该控制器创建一个简单视图. 完成MVC基础之后,我们就可以让一切运行起来了.

迁移和应用测试

EF迁移通常是一件简单的事情, 但一旦牵涉到Docker, 这个过程变得更加复杂. 在我们系列的下一篇文章中, 我们将探索奇妙的曲折路径,使这些迁移工作在我们的 Docker solution,但是现在,我们只想运行迁移.

所有配置和迁移文件都包含在我们的存储库中. 让我们将整个项目克隆到本地机器并执行迁移:

Git克隆http://github.com/theZetrax/dot-net-on-linux.git
cd ./ dot-net-on-linux
Docker composer up

The docker composer 操作构建我们的应用程序,运行迁移,并启动我们的ASP.. NET应用程序 .NET runtime. 要访问运行解决方案,请访问 http://localhost:8080/Shoes.

尽管我们的应用程序接口很简单, 它演示了所有层的功能, 从视图到数据库.

.. NET在Linux上工作

See the full repository 查看我们解决方案的概述. 下一篇文章将详细介绍我们的迁移, 以及使Docker镜像精简的技巧和技巧.

.NET Linux不仅仅是一个白日梦:它是一种可行的语言、运行时和操作系统组合. Many 在Visual Studio中成长起来的开发者 可能没有使用经验 .NET CLI,但这些工具是有效和强大的.

Toptal Engineering博客向 Henok Tsegaye 查看本文中提供的代码示例.

了解基本知识

  • What is .NET Core CLI?

    .. NET Core CLI,现在称为 .. NET CLI,包括可用于任何命令行接口 .NET-supported平台. 我们将这些工具用于项目创建、搭建、构建和辅助执行.

  • Can you build a .. NET框架?

    是的,发展 .. NET在Linux上得到很好的支持.

  • Is .NET Core在Linux上很好?

    .. NET (Core)在Linux上是强大的. 对于生产使用,开发工具和运行时都足够健壮.

聘请Toptal这方面的专家.
Hire Now
Zablon Dawit的头像
Zablon Dawit

Located in 亚的斯亚贝巴,埃塞俄比亚

Member since 2021年12月15日

作者简介

Zablon是一个专注于ASP的全栈web开发人员.。NET和JavaScript. 他曾为多家公司开发企业软件,包括Pelmorex Corp .和S.R.E软件开发.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

工作经验

5

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

Toptal开发者

Join the Toptal® community.