找回密码
 立即注册
快捷导航

[.NET] ASP.NET Core API

[复制链接]
妙笔生花 2023-9-1 05:32:21 | 显示全部楼层
本帖最后由 妙笔生花 于 2023-10-18 02:03 编辑

ASP.NET Core API

controller格式

[Route("api/[controller]")]
[ApiController]    // 指示控制器响应 Web API 请求。
public class TodoItemsController : ControllerBase
{
    private readonly TodoContext _context;

    // 使用 DI 将数据库上下文 (TodoContext) 注入到控制器中。
    public TodoItemsController(TodoContext context)
    {
        _context = context;
    }

    // GET: api/TodoItems
    [HttpGet]
    public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItems()
    {
        if (_context.TodoItems == null)
        {
            return NotFound();
        }
        return await _context.TodoItems.ToListAsync();
    }

    // GET: api/TodoItems/5
    [HttpGet("{id}")]
    public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
    {
        if (_context.TodoItems == null) return NotFound();
        var todoItem = await _context.TodoItems.FindAsync(id);
        if (todoItem == null) return NotFound();
        return todoItem;
    }

    // PUT: api/TodoItems/5
    [HttpPut("{id}")]
    public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
    {
        if (id != todoItem.Id) return BadRequest();
        _context.Entry(todoItem).State = EntityState.Modified;
        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!TodoItemExists(id)) return Conflict();
            else throw;
        }
        return NoContent();
    }

    // POST: api/TodoItems
    [HttpPost]
    public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
    {
        if (_context.TodoItems == null) return Problem("Entity set 'TodoContext.TodoItems'  is null.");
        _context.TodoItems.Add(todoItem);
        await _context.SaveChangesAsync();
        return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
    }

    // DELETE: api/TodoItems/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteTodoItem(long id)
    {
        if (_context.TodoItems == null) return NotFound();
        var todoItem = await _context.TodoItems.FindAsync(id);
        if (todoItem == null) return NotFound();
        _context.TodoItems.Remove(todoItem);
        await _context.SaveChangesAsync();
        return NoContent();
    }

    private bool TodoItemExists(long id) => (_context.TodoItems?.Any(e => e.Id == id)).GetValueOrDefault();
}

TodoContext 上下文:

using Microsoft.EntityFrameworkCore;

namespace TodoApi.Models
{
    public class TodoContext : DbContext
    {
        public TodoContext(DbContextOptions<TodoContext> options)
            : base(options)
        {

        }

        public DbSet<TodoItem> TodoItems { get; set; } = null!;
    }
}

Program.cs

using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

builder.Services.AddDbContext<TodoContext>(opt =>
{
    // 使用内存数据库,需要安装:Microsoft.EntityFrameworkCore.InMemory
    opt.UseInMemoryDatabase("TodoList");
    // 控制台输出日志
    opt.LogTo(Console.WriteLine);
});

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

IActionResult 返回:

  • return View();

  • return Ok("111");   // 200

  • return Content("1111");   // 200

  • return BadRequest();   // 400

  • return NotFound();    // 404

  • return Conflict();    // 409 表示请求的操作与当前资源冲突,一般用于更新(PUT和PATCH)

  • return Forbid();    // 500

  • return Unauthorized();    // 401

  • return UnprocessableEntity();    // 422

  • return Accepted();    // 202

  • return NotContent();

  • return CreatedAtAction("Index", new { id = todoItem.Id }, todoItem);

  • return new ObjectResult(model);

    • 成功返回201(表示在服务器上创建新资源)

    • 
      HTTP/1.1 201 Created
      Content-Type: application/json; charset=utf-8
      Date: Thu, 31 Aug 2023 16:07:45 GMT
      Location: https://localhost:7033/api/TodoItems/1
      Server: Kestrel
      Transfer-Encoding: chunked
      ---------------------------
      {
      "id": 1,
      "name": "walk dog",
      "isComplete": true
      }```

Linq

  • ToList()

    • List<Employee> lst = list.Where(e=>e.Salary>1000).ToList();
  • ToArray()

    • Employee[] arr = list.Where(e=>e.Salary>1000).ToArray();
  • Single()   查询1条数据,如果查询出有多条或者没有就报错;

  • SingleAsync()    查询1条数据,查询有多条就报错,没有就返回数据默认值比如 null/0;

  • First()    查询1条数据,有多条也返回1条,没有就报错;

  • FirstOrDefault()    查询1条数据,有多条也返回1条,没有就返回数据默认值比如 null/0;

  • Find()    根据主键查找

  • OrderBy()/ThenBy()    正序排序;

  • OrderByDescending()/ThenByDescending()    倒序排序;

    • list.OrderBy(e => e.Age).ThenByDescending(e => e.Salary)
  • Remove()    移除

  • Any()    是否至少有一条数据,如果一条都没有,返回False,否则返回True

    • list.Any(e => e.Salary > 8000);nums.Where(e => e > 8000).Any();
  • Skip(n)    跳过n条数据

  • Take(n)    获取n条数据

    • 获取从第2条开始获取3条数据  list.Skip(2).Take(3);
  • Max()

  • Min()

  • Average()

  • Sum

  • Count

  • GroupBy

请求方法

  • GET   查询

  • POST   添加

  • PATCH  部分更新,

    • 200 OK:表示 PATCH 请求成功,并且成功应用了部分更新。
    • 204 No Content:表示 PATCH 请求成功,但没有返回任何内容。通常用于表示成功更新,但不需要返回更新后的资源。
    • 400 Bad Request:表示请求无效,可能是由于请求体格式错误或无效的操作引起的。
    • 404 Not Found:表示未找到要更新的资源。
    • 409 Conflict:表示请求的操作与当前资源状态冲突,例如在执行部分更新时发生了冲突。
  • PUT  全量更新,需要客户端发送整个更新的实体,而不仅仅是更改。

    • 200 OK:表示 PUT 请求成功,并且成功更新了资源。可以在响应体中返回更新后的资源。
    • 204 Not Content:表示 PUT 请求成功,但没有返回任何内容。通常用于表示成功更新,但不需要返回更新后的资源。
    • 201 Created:表示 PUT 请求成功,并且成功创建了新资源。可以在响应体中返回新创建的资源。
    • 400 Bad Request:表示请求无效,可能是由于请求体格式错误或无效的操作引起的。
    • 404 Not Found:表示未找到要更新的资源。
    • 409 Conflict:表示请求的操作与当前资源状态冲突,例如在执行更新
  • DELETE  删除

状态码:

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/201

2××系列代表请求已成功被服务器接收、理解并接受,这系列中常见的有200状态码和201状态码。

  • 200状态码:表示请求已成功,请求所希望的响应头或数据体将随此响应返回。
  • 201状态码:表示请求成功,服务器创建了新的资源,并且其URI已经随Location请求头信息返回。假如需要的资源无法及时建立的话,应当返回202 Accepted。

3××系列代表需要客户端采取进一步的操作才能完成请求,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。这系列中常见的有301状态码和302状态码。

  • 301状态码:被请求的资源已永久移动到新位置。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置。
  • 302状态码:请求的资源临时从不同的URI响应请求,但请求者应继续使用原有位置来进行以后的请求。

分页

[HttpGet]
public async Task<IActionResult> GetArticlesByPage(int pageNumber, int pageSize)
{
    var articles = await _dbcontext.Articles
        .Skip((pageNumber - 1) * pageSize)
        .Take(pageSize)
        .ToListAsync();
    return Ok(articles);
}

// 从数据库上下文中获取指定页码的文章
// 使用Skip方法跳过指定数量的记录,然后使用Take方法获取指定数量的记录
// 请注意,这个方法假设页码从1开始,而不是从0开始。如果需要从0开始,请将(pageNumber - 1)更改为pageNumber。
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id) return BadRequest();
    _context.Entry(todoItem).State = EntityState.Modified;
    await _context.SaveChangesAsync();
    return NoContent();
}

上述的代码使用分布式锁(Redis)解决并发冲突

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

温馨提示

关于 注册码 问题

      由于近期经常大量注册机器人注册发送大量广告,本站开启免费入群领取注册码注册网站账号,注册码在群公告上贴着...

关于 注册码 问题

      由于近期经常大量注册机器人注册发送大量广告,本站开启免费入群领取注册码注册网站账号,注册码在群公告上贴着...

Archiver|手机版|小黑屋|DLSite

GMT+8, 2024-11-22 16:31

Powered by Discuz! X3.5 and PHP8

快速回复 返回顶部 返回列表