C# Web 开发从入门到实践

ASP.NET Core 框架使用指南


一、基础入门

1. 什么是 ASP.NET Core?

ASP.NET Core 是一个跨平台、高性能的开源 Web 框架,用于构建现代的、基于云的、连接的互联网应用。

特点:

  • 跨平台(Windows、Linux、macOS)
  • 高性能
  • 开源
  • 统一的 MVC 和 Web API 框架
  • 依赖注入内置

2. 创建第一个项目

bash 复制代码
# 安装 .NET SDK(如果尚未安装)
# 从 https://dotnet.microsoft.com/download 下载

# 创建新的 Web API 项目
dotnet new webapi -n MyFirstApi

# 进入项目目录
cd MyFirstApi

# 运行项目
dotnet run

项目结构:

复制代码
MyFirstApi/
├── Controllers/          # 控制器
├── Program.cs           # 应用入口
├── Startup.cs           # 启动配置(旧版)
└── MyFirstApi.csproj    # 项目文件

3. 第一个 API 控制器

csharp 复制代码
// Controllers/HelloController.cs
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class HelloController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok("Hello, World!");
    }

    [HttpGet("{name}")]
    public IActionResult Greet(string name)
    {
        return Ok($"Hello, {name}!");
    }
}

访问:http://localhost:5000/api/hello


二、核心概念

1. 依赖注入(DI)

ASP.NET Core 内置依赖注入容器:

csharp 复制代码
// 定义服务
public interface IMessageService
{
    string GetMessage();
}

public class MessageService : IMessageService
{
    public string GetMessage() => "Hello from Service!";
}

// 在 Program.cs 中注册
var builder = WebApplication.CreateBuilder(args);

// 注册服务
builder.Services.AddScoped<IMessageService, MessageService>();

var app = builder.Build();

// 在控制器中使用
public class HelloController : ControllerBase
{
    private readonly IMessageService _messageService;

    public HelloController(IMessageService messageService)
    {
        _messageService = messageService;
    }

    [HttpGet]
    public IActionResult Get()
    {
        return Ok(_messageService.GetMessage());
    }
}

服务生命周期:

  • Transient:每次请求都创建新实例
  • Scoped:每个 HTTP 请求一个实例
  • Singleton:整个应用程序生命周期一个实例

2. 中间件(Middleware)

中间件是处理 HTTP 请求和响应的管道:

csharp 复制代码
var app = builder.Build();

// 自定义中间件
app.Use(async (context, next) =>
{
    Console.WriteLine($"请求: {context.Request.Path}");

    await next();

    Console.WriteLine($"响应状态: {context.Response.StatusCode}");
});

// 使用内置中间件
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

中间件顺序很重要!

3. 配置

csharp 复制代码
// appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=mydb;"
  }
}

// 在代码中读取配置
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");

var logLevel = builder.Configuration["Logging:LogLevel:Default"];

三、Web API 开发

1. RESTful API 设计

csharp 复制代码
// Models/TodoItem.cs
public class TodoItem
{
    public int Id { get; set; }
    public string Title { get; set; }
    public bool IsCompleted { get; set; }
}

// Controllers/TodosController.cs
[ApiController]
[Route("api/[controller]")]
public class TodosController : ControllerBase
{
    private static List<TodoItem> _todos = new();

    // GET: api/todos
    [HttpGet]
    public ActionResult<IEnumerable<TodoItem>> GetAll()
    {
        return Ok(_todos);
    }

    // GET: api/todos/5
    [HttpGet("{id}")]
    public ActionResult<TodoItem> GetById(int id)
    {
        var todo = _todos.FirstOrDefault(t => t.Id == id);
        if (todo == null)
            return NotFound();
        return Ok(todo);
    }

    // POST: api/todos
    [HttpPost]
    public ActionResult<TodoItem> Create(TodoItem todo)
    {
        todo.Id = _todos.Any() ? _todos.Max(t => t.Id) + 1 : 1;
        _todos.Add(todo);
        return CreatedAtAction(nameof(GetById), new { id = todo.Id }, todo);
    }

    // PUT: api/todos/5
    [HttpPut("{id}")]
    public IActionResult Update(int id, TodoItem todo)
    {
        var existing = _todos.FirstOrDefault(t => t.Id == id);
        if (existing == null)
            return NotFound();

        existing.Title = todo.Title;
        existing.IsCompleted = todo.IsCompleted;
        return NoContent();
    }

    // DELETE: api/todos/5
    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
        var todo = _todos.FirstOrDefault(t => t.Id == id);
        if (todo == null)
            return NotFound();

        _todos.Remove(todo);
        return NoContent();
    }
}

2. 数据验证

csharp 复制代码
using System.ComponentModel.DataAnnotations;

public class TodoItem
{
    public int Id { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 3)]
    public string Title { get; set; }

    public bool IsCompleted { get; set; }
}

// 在控制器中自动验证
[HttpPost]
public ActionResult<TodoItem> Create([FromBody] TodoItem todo)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // 创建逻辑...
}

四、数据库集成(Entity Framework Core)

1. 设置 DbContext

bash 复制代码
# 安装 EF Core 包
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
csharp 复制代码
// Data/AppDbContext.cs
using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {
    }

    public DbSet<TodoItem> Todos { get; set; }
}

2. 配置连接字符串

csharp 复制代码
// Program.cs
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")
    ));

3. 使用数据库

csharp 复制代码
// Controllers/TodosController.cs
public class TodosController : ControllerBase
{
    private readonly AppDbContext _context;

    public TodosController(AppDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<TodoItem>>> GetAll()
    {
        return await _context.Todos.ToListAsync();
    }

    [HttpPost]
    public async Task<ActionResult<TodoItem>> Create(TodoItem todo)
    {
        _context.Todos.Add(todo);
        await _context.SaveChangesAsync();
        return CreatedAtAction(nameof(GetById), new { id = todo.Id }, todo);
    }
}

4. 数据库迁移

bash 复制代码
# 创建初始迁移
dotnet ef migrations add InitialCreate

# 应用迁移
dotnet ef database update

五、身份验证与授权

1. JWT 认证

bash 复制代码
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
csharp 复制代码
// 配置 JWT
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "yourdomain.com",
            ValidAudience = "yourdomain.com",
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes("your-secret-key"))
        };
    });

app.UseAuthentication();
app.UseAuthorization();

2. 授权

csharp 复制代码
[Authorize]  // 需要认证
[HttpGet("protected")]
public IActionResult GetProtected()
{
    return Ok("This is protected!");
}

[Authorize(Roles = "Admin")]
[HttpGet("admin")]
public IActionResult GetAdminOnly()
{
    return Ok("Admin only!");
}

六、高级特性

1. SignalR 实时通信

bash 复制代码
dotnet add package Microsoft.AspNetCore.SignalR
csharp 复制代码
// Hubs/ChatHub.cs
public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

// Program.cs
app.MapHub<ChatHub>("/chathub");

2. 后台服务

csharp 复制代码
public class TimedHostedService : BackgroundService
{
    private readonly ILogger<TimedHostedService> _logger;

    public TimedHostedService(ILogger<TimedHostedService> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(5000, stoppingToken);
        }
    }
}

// 注册
builder.Services.AddHostedService<TimedHostedService>();

3. 健康检查

bash 复制代码
dotnet add package Microsoft.AspNetCore.Diagnostics.HealthChecks
dotnet add package AspNetCore.HealthChecks.NpgSql
csharp 复制代码
builder.Services.AddHealthChecks()
    .AddNpgSql(connectionString);

app.MapHealthChecks("/health");

七、部署

1. Docker 部署

dockerfile 复制代码
# Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["MyFirstApi.csproj", "./"]
RUN dotnet restore "MyFirstApi.csproj"
COPY . .
RUN dotnet publish "MyFirstApi.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyFirstApi.dll"]
bash 复制代码
# 构建镜像
docker build -t myfirstapi .

# 运行容器
docker run -p 8080:80 myfirstapi

2. Linux 部署

bash 复制代码
# 发布应用
dotnet publish -c Release -o ./publish

# 运行
cd publish
dotnet MyFirstApi.dll

八、最佳实践

  1. 使用异步方法:所有 I/O 操作都应该异步
  2. 日志记录 :使用 ILogger 进行日志记录
  3. 错误处理:使用全局异常处理中间件
  4. API 版本控制:使用版本管理 API
  5. 配置管理:使用环境变量和配置文件
  6. 单元测试:编写单元测试和集成测试

总结

ASP.NET Core 是一个强大、灵活的 Web 框架。通过掌握:

  • 基础概念(DI、中间件)
  • Web API 开发
  • 数据库集成(EF Core)
  • 身份验证和授权
  • 高级特性(SignalR、后台服务)

你就可以构建企业级的 Web 应用了!


下一步:

  • 尝试创建自己的项目
  • 学习更多中间件
  • 探索微服务架构
相关推荐
穗余2 小时前
java大模型应用开发里的SseEmitter和websocket区别
java·开发语言·人工智能·websocket
大黄说说2 小时前
Vue 3 + Vite 高性能项目最佳实践(2026 版)
前端·javascript·vue.js
数据服务生2 小时前
围棋-html版本
前端·html
好家伙VCC2 小时前
# 发散创新:用 Rust构建高并发虚拟世界引擎核心模块在当今游戏开发与元宇宙构建中,**虚拟世界的性能瓶颈往往不是图形渲染,而是底
java·开发语言·python·rust·图形渲染
Liu628882 小时前
C++中的状态模式
开发语言·c++·算法
smchaopiao2 小时前
使用C语言打印几何图形:从三角形到菱形
c语言·开发语言·算法
JohnsonXin2 小时前
一次线上白屏排查:静态 import 是如何悄悄破坏 Webpack 共享 Chunk 的
前端·webpack·node.js
爱滑雪的码农2 小时前
Java基础六:条件语句与switch case
java·开发语言