You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Web API 如何仅向已登录用户展示其所属的Mandate数据

解决方案

步骤1:注册IHttpContextAccessor服务(用于获取当前登录用户ID)

在.NET 6+的Program.cs中添加服务注册:

builder.Services.AddHttpContextAccessor();

步骤2:在MandateService中注入服务,实现获取当前登录用户ID的逻辑

修改MandateService的构造函数,注入IHttpContextAccessor,同时新增获取当前用户ID的方法:

using System.Security.Claims;
using Microsoft.AspNetCore.Http;

private readonly IHttpContextAccessor _httpContextAccessor;

// 构造函数新增注入参数
public MandateService(IUnitOfWork unitOfWork, IUriPaginationService uriPaginationService, IHttpContextAccessor httpContextAccessor)
{
    _unitOfWork = unitOfWork;
    _uriPaginationService = uriPaginationService;
    _httpContextAccessor = httpContextAccessor;
}

// 获取当前登录用户ID
private int? GetCurrentUserId()
{
    var userIdClaim = _httpContextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    if (int.TryParse(userIdClaim, out int userId))
    {
        return userId;
    }
    // 未登录或Claim不存在则返回空
    return null;
}

注意:如果你的登录逻辑使用自定义Claim存储用户ID,需要将ClaimTypes.NameIdentifier替换为你自定义的Claim类型。

步骤3:扩展仓储接口支持筛选和关联查询

在IBaseRepository新增支持筛选和Include导航属性的方法,方便后续条件查询:

// IBaseRepository接口新增方法定义
public interface IBaseRepository<T> where T : EntityBase
{
    // 原有方法保留,新增如下方法
    Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> filter = null, params Expression<Func<T, object>>[] includes);
}

// BaseRepository中实现该方法
public async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> filter = null, params Expression<Func<T, object>>[] includes)
{
    IQueryable<T> query = _context.Set<T>();
    // 加载关联导航属性
    if (includes != null)
    {
        query = includes.Aggregate(query, (current, include) => current.Include(include));
    }
    // 应用筛选条件
    if (filter != null)
    {
        query = query.Where(filter);
    }
    return await query.ToListAsync();
}

步骤4:修改MandateService查询逻辑,过滤用户关联数据

调整GetAll和GetMandates方法的查询逻辑,只返回当前用户关联的Mandate数据:

public async Task<ResponsePagination<GenericPagination<MandateGetDto>>> GetAll(int page, int sizeByPage)
{
    string nextRoute = null, previousRoute = null;
    var currentUserId = GetCurrentUserId();
    // 未登录直接返回空结果
    if (!currentUserId.HasValue)
    {
        var emptyPagination = GenericPagination<MandateGetDto>.Create(new List<MandateGetDto>(), page, sizeByPage);
        return new ResponsePagination<GenericPagination<MandateGetDto>>(emptyPagination);
    }
    // 过滤规则:Mandate关联的Merchant的UserId等于当前登录用户ID
    IEnumerable<Mandate> data = await _unitOfWork.MandateRepository.GetAsync(
        filter: m => m.Merchant.UserId == currentUserId.Value,
        includes: m => m.Merchant
    );

    // 后续原有映射、分页逻辑保持不变
    var mapper = new EntityMapper();
    var mandatesDto = data.Select(m => mapper.FromMandateToMandateGetDto(m)).ToList();

    GenericPagination<MandateGetDto> objGenericPagination = GenericPagination<MandateGetDto>.Create(mandatesDto, page, sizeByPage);
    ResponsePagination<GenericPagination<MandateGetDto>> response = new ResponsePagination<GenericPagination<MandateGetDto>>(objGenericPagination);
    response.CurrentPage = objGenericPagination.CurrentPage;
    response.HasNextPage = objGenericPagination.HasNextPage;
    response.HasPreviousPage = objGenericPagination.HasPreviousPage;
    response.PageSize = objGenericPagination.PageSize;
    response.TotalPages = objGenericPagination.TotalPages;
    response.TotalRecords = objGenericPagination.TotalRecords;
    response.Data = objGenericPagination;

    if (response.HasNextPage)
    {
        nextRoute = $"/mandates?page={(page + 1)}";
        response.NextPageUrl = _uriPaginationService.GetPaginationUri(page, nextRoute).ToString();
    }
    else
    {
        response.NextPageUrl = null;
    }

    if (response.HasPreviousPage)
    {
        previousRoute = $"/mandates?page={(page - 1)}";
        response.PreviousPageUrl = _uriPaginationService.GetPaginationUri(page, previousRoute).ToString();
    }
    else
    {
        response.PreviousPageUrl = null;
    }
    return response;
}

// 同理修改GetMandates方法
public async Task<IEnumerable<Mandate>> GetMandates()
{
    var currentUserId = GetCurrentUserId();
    if (!currentUserId.HasValue)
    {
        return Enumerable.Empty<Mandate>();
    }
    return await _unitOfWork.MandateRepository.GetAsync(
        filter: m => m.Merchant.UserId == currentUserId.Value,
        includes: m => m.Merchant
    );
}

优化建议

如果数据量较大,可以将分页逻辑下移到数据库层面执行,避免先查询全量数据再在内存分页,减少内存占用和查询耗时。

内容的提问来源于stack exchange,提问作者Olugbenga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 04:06:10