C# и .NET на сервере
Проверка установки
# Версия .NET SDK
dotnet --version
# 6.0+ или 7.0+
# Список установленных SDK
dotnet --list-sdks
# Список runtime
dotnet --list-runtimes
# Информация о среде
dotnet --info
Структура .NET на Linux
# Пути .NET
/usr/share/dotnet/ # Основная установка
├── dotnet # Основной бинарник
├── sdk/ # Установленные SDK
├── runtime/ # Runtime версии
└── templates/ # Шаблоны проектов
# Проекты пользователя
/home/kollokpoi/.dotnet/ # Кэш, инструменты
/home/kollokpoi/.nuget/ # Кэш пакетов NuGet
Создание и управление проектами
Создание проектов
# Список доступных шаблонов
dotnet new list
# Консольное приложение
dotnet new console -n MyConsoleApp
# Веб-API
dotnet new webapi -n MyApi
# MVC приложение
dotnet new mvc -n MyWebApp
# Блазор приложение
dotnet new blazorserver -n MyBlazorApp
# Класс-библиотека
dotnet new classlib -n MyLibrary
# xUnit тесты
dotnet new xunit -n MyTests
Управление проектом
# Сборка проекта
dotnet build
dotnet build --configuration Release
# Запуск приложения
dotnet run
dotnet run --project MyProject.csproj
# Публикация
dotnet publish -c Release -o ./publish
dotnet publish --self-contained # включая runtime
# Очистка
dotnet clean
dotnet clean && dotnet build # полная пересборка
Пакетный менеджер NuGet
Управление пакетами
# Добавление пакета
dotnet add package Newtonsoft.Json
dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 7.0.0
# Удаление пакета
dotnet remove package Newtonsoft.Json
# Восстановление пакетов
dotnet restore
# Список установленных пакетов
dotnet list package
dotnet list package --outdated
# Обновление пакетов
dotnet outdated # требует установки глобально
Файлы конфигурации
<!-- MyProject.csproj -->
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>
Веб-фреймворки
ASP.NET Core Web API
# Создание API проекта
dotnet new webapi -n MyApi
cd MyApi
# Запуск
dotnet run
# Доступно: http://192.168.0.103:5000 и https://192.168.0.103:5001
// Program.cs минимальный API
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapGet("/api/users/{id}", (int id) => new { Id = id, Name = "User" });
app.Run();
ASP.NET Core MVC
dotnet new mvc -n MyWebApp
dotnet new mvc --auth Individual # с аутентификацией
// Контроллер
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok(new[] { "User1", "User2" });
}
}
Blazor Server
dotnet new blazorserver -n MyBlazorApp --no-https
Работа с базами данных
Entity Framework Core
# Установка EF Core
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
# Для SQLite
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
# Для PostgreSQL
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
Миграции EF Core
# Создание миграции
dotnet ef migrations add InitialCreate
dotnet ef migrations add AddUserTable
# Обновление базы данных
dotnet ef database update
# Откат миграции
dotnet ef database update PreviousMigrationName
# Создание скрипта SQL
dotnet ef migrations script -o migration.sql
Контекст базы данных
public class AppDbContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// Для SQL Server на нашем сервере
options.UseSqlServer("Server=192.168.0.103;Database=MyDb;User Id=sa;Password=your_password;");
// Для PostgreSQL
// options.UseNpgsql("Host=192.168.0.103;Database=MyDb;Username=kollokpoi");
}
}
Инструменты разработки
Глобальные инструменты
# Установка глобальных инструментов
dotnet tool install -g dotnet-ef
dotnet tool install -g dotnet-reportgenerator-globaltool
dotnet tool install -g dotnet-outdated
# Список установленных инструментов
dotnet tool list -g
# Обновление инструментов
dotnet tool update -g dotnet-ef
Полезные инструменты
# dotnet-ef - Entity Framework CLI
# dotnet-outdated - проверка устаревших пакетов
# dotnet-trace - профилирование
# dotnet-counters - мониторинг метрик
# dotnet-dump - отладка дампов памяти
Развертывание на сервере
Публикация приложения
# Публикация с зависимым runtime
dotnet publish -c Release -r linux-x64 --self-contained true -o ./publish
# Публикация без runtime (требует установленного .NET на сервере)
dotnet publish -c Release -o ./publish
Systemd сервис для .NET приложения
# /etc/systemd/system/myapp.service
[Unit]
Description=My .NET Web API
After=network.target
[Service]
Type=exec
User=kollokpoi
Group=kollokpoi
WorkingDirectory=/home/kollokpoi/myapp/publish
ExecStart=/home/kollokpoi/myapp/publish/MyApi
Restart=always
RestartSec=10
KillSignal=SIGINT
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=ASPNETCORE_URLS=http://0.0.0.0:5000
[Install]
WantedBy=multi-user.target
# Управление сервисом
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
sudo systemctl status myapp
sudo journalctl -u myapp -f # просмотр логов
Nginx прокси для .NET приложения
# /etc/nginx/sites-available/dotnet-app
server {
listen 80;
server_name api.local;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Модульное тестирование
xUnit тесты
# Создание тестового проекта
dotnet new xunit -n MyProject.Tests
# Запуск тестов
dotnet test
dotnet test --verbosity normal
dotnet test --filter "Category=Integration"
Пример теста
public class CalculatorTests
{
[Fact]
public void Add_TwoNumbers_ReturnsSum()
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(2, 3);
// Assert
Assert.Equal(5, result);
}
[Theory]
[InlineData(1, 2, 3)]
[InlineData(5, 5, 10)]
public void Add_MultipleCases_ReturnsCorrectSum(int a, int b, int expected)
{
var calculator = new Calculator();
var result = calculator.Add(a, b);
Assert.Equal(expected, result);
}
}
Конфигурация и окружение
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=192.168.0.103;Database=MyDb;User Id=sa;Password=***;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Переменные окружения
# Установка переменных окружения
export ASPNETCORE_ENVIRONMENT=Development
export ConnectionStrings__DefaultConnection="Server=192.168.0.103;Database=MyDb;..."
# В коде
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
var environment = builder.Environment.EnvironmentName;
Мониторинг и логирование
Встроенное логирование
public class MyService
{
private readonly ILogger<MyService> _logger;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
}
public void DoWork()
{
_logger.LogInformation("Starting work");
_logger.LogError("Something went wrong");
_logger.LogDebug("Debug information");
}
}
Serilog (расширенное логирование)
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.File
// Program.cs
Log.Logger = new LoggerConfiguration()
.WriteTo.File("/var/log/myapp/log-.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
Туториалы и документация
Официальные
Практические
Видеокурсы
Полезные пакеты
# Веб-разработка
dotnet add package Swashbuckle.AspNetCore # Swagger
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
# Базы данных
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL # PostgreSQL
dotnet add package Pomelo.EntityFrameworkCore.MySql # MySQL
dotnet add package Microsoft.EntityFrameworkCore.Sqlite # SQLite
# Утилиты
dotnet add package AutoMapper
dotnet add package FluentValidation
dotnet add package MediatR
# Тестирование
dotnet add package xunit
dotnet add package Moq
dotnet add package FluentAssertions
# Логирование
dotnet add package Serilog.AspNetCore
Решение проблем
"Could not execute because the specified command or file was not found"
# Восстановить проект
dotnet restore
# Проверить наличие SDK
dotnet --list-sdks
# Очистить кэш NuGet
dotnet nuget locals all --clear
"Unable to bind to http://localhost:5000 on the IPv6 loopback interface"
# Запустить на конкретном интерфейсе
dotnet run --urls "http://0.0.0.0:5000"
# Или в коде
app.Urls.Add("http://0.0.0.0:5000");
Ошибки с Entity Framework
# Установить EF Tools
dotnet tool install --global dotnet-ef
# Проверить подключение к БД
dotnet ef database update --verbose
Недостаточно памяти
# Ограничить память для сборки
export DOTNET_CLI_TELEMETRY_OPTOUT=1
dotnet build --no-incremental
# Очистить кэш
dotnet clean
rm -rf bin/ obj/
Используй C#/.NET для: корпоративных API, микросервисов, веб-приложений и интеграции с MSSQL на сервере 192.168.0.103.