2. 前置條件與項目結(jié)構(gòu)回顧


3. Category GET 接口實現(xiàn)

3.1 定義接口(ICategoryRepository)

Interfaces/ICategoryRepository.cs,定義三種查詢方法:

public interface ICategoryRepository
{
    IReadOnlyCollection < Category > GetCategories();             // 列表
    Category GetCategory(int id);                              // 詳情
    IReadOnlyCollection < Pokemon >  GetPokemonsByCategory(int id); // 關(guān)聯(lián)查詢
    bool CategoryExists(int id);                               // 存在性校驗
}

3.2 倉儲實現(xiàn)(CategoryRepository)

Repositories/CategoryRepository.cs

public class CategoryRepository : ICategoryRepository
{
    private readonly AppDbContext _context;
    public CategoryRepository(AppDbContext context) = >  _context = context;

    public IReadOnlyCollection < Category >  GetCategories() = >
        _context.Categories.ToList();

    public Category GetCategory(int id) = >
        _context.Categories.FirstOrDefault(c = > c.Id == id);

    public IReadOnlyCollection < Pokemon > GetPokemonsByCategory(int id) = >
        _context.PokemonCategories
                .Where(pc = > pc.Category.Id == id)
                .Select(pc = > pc.Pokemon)
                .ToList();

    public bool CategoryExists(int id) = >
        _context.Categories.Any(c = > c.Id == id);
}

3.3 DTO 與映射配置(CategoryDto)

3.4 控制器實現(xiàn)(CategoryController)

Controllers/CategoryController.cs 中注入倉儲與映射器,并實現(xiàn)三條 GET:

[ApiController]
[Route("api/[controller]")]
public class CategoryController : ControllerBase
{
    private readonly ICategoryRepository _repo;
    private readonly IMapper _mapper;

    public CategoryController(ICategoryRepository repo, IMapper mapper)
    {
        _repo = repo;
        _mapper = mapper;
    }

    // GET api/category
    [HttpGet]
    public ActionResult < IReadOnlyCollection < CategoryDto > > GetCategories()
    {
        var categories = _repo.GetCategories();
        return Ok(_mapper.Map < IReadOnlyCollection < CategoryDto > > (categories));
    }

    // GET api/category/{id}
    [HttpGet("{id}")]
    public ActionResult < CategoryDto > GetCategory(int id)
    {
        if (!_repo.CategoryExists(id))
            return NotFound($"Category {id} 未找到。");
        var category = _repo.GetCategory(id);
        return Ok(_mapper.Map < CategoryDto > (category));
    }

    // GET api/category/{id}/pokemons
    [HttpGet("{id}/pokemons")]
    public ActionResult < IReadOnlyCollection < PokemonDto > > GetPokemonsByCategory(int id)
    {
        if (!_repo.CategoryExists(id))
            return NotFound($"Category {id} 未找到。");
        var pokemons = _repo.GetPokemonsByCategory(id);
        return Ok(_mapper.Map < IReadOnlyCollection < PokemonDto > > (pokemons));
    }
}

4. Country GET 接口實現(xiàn)

4.1 定義接口(ICountryRepository)

Interfaces/ICountryRepository.cs

public interface ICountryRepository
{
    IReadOnlyCollection < Country > GetCountries();             // 列表
    Country GetCountry(int id);                              // 詳情
    IReadOnlyCollection < Owner > GetOwnersByCountry(int id);    // 關(guān)聯(lián)查詢
    bool CountryExists(int id);                              // 存在性校驗
}

4.2 倉儲實現(xiàn)(CountryRepository)

Repositories/CountryRepository.cs

public class CountryRepository : ICountryRepository
{
    private readonly AppDbContext _context;
    public CountryRepository(AppDbContext context) = > _context = context;

    public IReadOnlyCollection < Country > GetCountries() = >
        _context.Countries.ToList();

    public Country GetCountry(int id) = >
        _context.Countries.FirstOrDefault(c = > c.Id == id);

    public IReadOnlyCollection < Owner > GetOwnersByCountry(int id) = >
        _context.Owners
                .Where(o = > o.Country.Id == id)
                .ToList();

    public bool CountryExists(int id) = >
        _context.Countries.Any(c = > c.Id == id);
}

4.3 DTO 與映射配置(CountryDto)

4.4 控制器實現(xiàn)(CountryController)

[ApiController]
[Route("api/[controller]")]
public class CountryController : ControllerBase
{
    private readonly ICountryRepository _repo;
    private readonly IMapper _mapper;

    public CountryController(ICountryRepository repo, IMapper mapper)
    {
        _repo = repo;
        _mapper = mapper;
    }

    // GET api/country
    [HttpGet]
    public ActionResult < IReadOnlyCollection<CountryDto > > GetCountries() = >
        Ok(_mapper.Map < IReadOnlyCollection<CountryDto > > (_repo.GetCountries()));

    // GET api/country/{id}
    [HttpGet("{id}")]
    public ActionResult < CountryDto > GetCountry(int id)
    {
        if (!_repo.CountryExists(id))
            return NotFound($"Country {id} 未找到。");
        return Ok(_mapper.Map < CountryDto > (_repo.GetCountry(id)));
    }

    // GET api/country/{id}/owners
    [HttpGet("{id}/owners")]
    public ActionResult < IReadOnlyCollection < OwnerDto > > GetOwnersByCountry(int id)
    {
        if (!_repo.CountryExists(id))
            return NotFound($"Country {id} 未找到。");
        var owners = _repo.GetOwnersByCountry(id);
        return Ok(_mapper.Map < IReadOnlyCollection < OwnerDto > > (owners));
    }
}

5. 測試與驗證(Swagger)

  1. 運行項目后打開 Swagger UI(/swagger)。
  2. Category 測試:

  3. Country 測試:

確認返回狀態(tài)碼與 DTO 格式符合預期,確保數(shù)據(jù)準確且不泄露多余字段。


6. 小結(jié)與最佳實踐

通過本篇示例,你已掌握為多種模型批量構(gòu)建 GET 接口的完整流程,進一步夯實了 API 開發(fā)實戰(zhàn)能力。下一篇,我們將繼續(xù)完成剩余 Controller,并切入 POST/PUT/DELETE 操作,敬請期待!

原文引自YouTube視頻:https://www.youtube.com/watch?v=bSvYErXVRtQ

上一篇:

ASP.NET Core Web API GET 請求全攻略|多場景 GET Endpoint 實戰(zhàn)

下一篇:

ASP.NET Core Web API GET 請求進階(三)|Owner、Review、Reviewer 接口實戰(zhàn)
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費