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

Asp.Net Core仓储层LinkGenerator.GetUriByAction未定义问题求助

仓储层的EmployeeLinks类
using Contracts;
using Microsoft.AspNetCore.Routing;
using Entities.LinkModels;
using Entities.Models;
using Shared.DataTransferObjects;
using Microsoft.AspNetCore.Mvc.Formatters;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace Repository.Extensions.Utility
{
    public class EmployeeLinks : IEmployeeLinks
    {
        private readonly LinkGenerator _linkGenerator;
        private readonly IDataShaper<EmployeeDto> _dataShaper;

        public EmployeeLinks(LinkGenerator linkGenerator, IDataShaper<EmployeeDto> dataShaper)
        {
            _linkGenerator = linkGenerator;
            _dataShaper = dataShaper;
        }

        public LinkResponse TryGenerateLinks(IEnumerable<EmployeeDto> employeesDto, string fields, Guid companyId, HttpContext httpContext)
        {
            var shapedEmployees = ShapeData(employeesDto, fields);
            if (ShouldGenerateLinks(httpContext))
                return ReturnLinkdedEmployees(employeesDto, fields, companyId, httpContext, shapedEmployees);

            return ReturnShapedEmployees(shapedEmployees);
        }
        private List<Entity> ShapeData(IEnumerable<EmployeeDto> employeesDto, string fields) =>
             _dataShaper.ShapeData(employeesDto, fields)
             .Select(e => e.Entity)
             .ToList();

        private bool ShouldGenerateLinks(HttpContext httpContext)
        {
            var mediaType = (MediaTypeHeaderValue)httpContext.Items["AcceptHeaderMediaType"];
            return mediaType.SubTypeWithoutSuffix.EndsWith("hateoas", StringComparison.InvariantCultureIgnoreCase);
        }

        private LinkResponse ReturnShapedEmployees(List<Entity> shapedEmployees) =>
         new LinkResponse { ShapedEntities = shapedEmployees };

        private LinkResponse ReturnLinkdedEmployees(IEnumerable<EmployeeDto> employeeDto, string fields, Guid companyId,
            HttpContext httpContext, List<Entity> shapedEmployees)
        {
            var employeeDtoList = employeeDto.ToList();

            for(var index = 0; index < shapedEmployees.Count; index++)
            {
                var employeeLinks = CreateLinksForEmployee(httpContext, companyId, employeeDtoList[index].Id, fields);
                shapedEmployees[index].Add("Links", employeeLinks);
            }

            var employeeCollection = new LinkCollectionWrapper<Entity>(shapedEmployees);
            var linkedEmployees = CreateLinksForEmployees(httpContext, employeeCollection);

            return new LinkResponse { HasLinks = true, LinkedEntities = linkedEmployees };
        }

        private List<Link> CreateLinksForEmployee(HttpContext httpContext, Guid companyId, Guid id, string fields = "")
        {
            var links = new List<Link>
            {
                new Link(_linkGenerator.GetUriByAction(httpContext, "GetEmployeeForCompany", "Employees", values: new {companyId, id, fields}),
                    "self",
                    "GET"),
                new Link(_linkGenerator.GetUriByAction(httpContext,"DeleteEmployeeForCompany", "Employees", values: new { companyId, id }),
                    "delete_employee",
                    "DELETE"),
                new Link(_linkGenerator.GetUriByAction(httpContext, "UpdateEmployeeForCompany", "Employees", values: new { companyId, id }),
                    "update_employee",
                    "PUT"),
                new Link(_linkGenerator.GetUriByAction(httpContext, "PartiallyUpdateEmployeeForCompany", "Employees", values: new { companyId, id }),
                    "partially_update_employee",
                    "PATCH")
            };
            return links;
        }

        private LinkCollectionWrapper<Entity> CreateLinksForEmployees(HttpContext httpContext, LinkCollectionWrapper<Entity> employeesWrapper)
        {
            employeesWrapper.Links.Add(new Link(_linkGenerator.GetUriByAction(httpContext, "GetEmployeesForCompany", values: new { }),
            "self",
            "GET"));
            return employeesWrapper;
        }
    }
}

我在表示层(即Controller)中使用LinkGenerator类时,GetUriByAction方法可正常运行无异常,但在仓储层的EmployeeLinks类中使用时却无法正常工作,出现如下错误:

'LinkGenerator' does not contain a definition for 'GetUriByAction' and no accessible extension method 'GetUriByAction' accepting a first argument of type 'LinkGenerator' could be found (are you missing a using directive or an assembly reference?).


解决方法

1. 添加必要的命名空间引用

GetUriByAction是ASP.NET Core MVC的扩展方法,定义在Microsoft.AspNetCore.Mvc.Routing命名空间下的LinkGeneratorMvcExtensions类中。当前仓储层代码仅引用了Microsoft.AspNetCore.Routing,缺少该命名空间导致编译器无法识别方法。

在EmployeeLinks类的using指令中添加:

using Microsoft.AspNetCore.Mvc.Routing;

2. 确保项目引用正确的依赖包

如果仓储层是独立类库项目:

  • .NET 6+版本:确保项目文件中包含<FrameworkReference Include="Microsoft.AspNetCore.App" />,引用ASP.NET Core共享框架。
  • .NET 5及更早版本:手动安装Microsoft.AspNetCore.Mvc.Core NuGet包。

补充说明

表示层的Controller默认会自动引用Microsoft.AspNetCore.Mvc相关命名空间,因此GetUriByAction可正常使用;而仓储层类库通常不会自动包含这些引用,需要手动添加才能调用该扩展方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:00:03