【问题标题】:LinkGenerator returns NULL Url while Url.Action doesn't ... WhyLinkGenerator 返回 NULL Url 而 Url.Action 不返回...为什么
【发布时间】:2019-06-15 18:54:15
【问题描述】:

在 ASP.NET Core 2.2 控制器上,我尝试通过 3 种方式生成链接:

var a = Url.Action(action: "GetContentByFileId", values: new { fileId = 1 });

var b = _linkGenerator.GetUriByAction(HttpContext, action: "GetContentByFileId", controller: "FileController", values: new { fileId = 1 });

var c = _linkGenerator.GetUriByAction(_httpContextAccessor.HttpContext, action: "GetContentByFileId", controller: "FileController", values: new { fileId = 1 });

结果

  • 在“a”中,使用 Url.Action 我得到正确的链接...

  • 在“b”和“c”中,我得到空值,我提供相同的数据......我想。

我在 Controller 中注入 LinkGenerator 并且它不是 null ...

我也在注入 HttpContextAccessor 并且在启动时有:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

文件控制器是

[ApiVersion("1.0", Deprecated = false), Route("v{apiVersion}")]
public class FileController : Controller {

  private readonly IHttpContextAccessor _httpContextAccessor;
  private readonly LinkGenerator _linkGenerator; 

  public FileController(IHttpContextAccessor httpContextAccessor, LinkGenerator linkGenerator) {

    _httpContextAccessor = httpContextAccessor;
    _linkGenerator = linkGenerator;

  }

  [HttpGet("files/{fileId:int:min(1)}")]
  public async Task<IActionResult> GetContentByFileId(FileGetModel.Request request) {
    // Remaining code
  }

我错过了什么?

更新

TanvirArjel 回答了控制器后缀之外的问题。

如果我注释以下代码行,所有网址都是正确的:

[ApiVersion("1.0", Deprecated = false), Route("v{apiVersion}")]

但是如果我在启动时添加前面的代码行和以下代码:

services.AddApiVersioning(x => {
  x.ApiVersionSelector = new CurrentImplementationApiVersionSelector(x);
  x.AssumeDefaultVersionWhenUnspecified = true;
  x.DefaultApiVersion = new ApiVersion(1, 0);
  x.ReportApiVersions = false;
});

然后 urls 变为 null ...

此 ApiVersion 在文件之前添加的是“v1.0”,因此它变为“v1.0/files”。

所以linkGenerator应该变成:

var b = _linkGenerator.GetUriByAction(HttpContext, 
  action: "GetContentByFileId", 
  controller: "File", 
  values: new { apiVersion = "1.0", fileId = 1 
});

问题

有没有办法在不指定的情况下将 apiVersion 集成到 LinkGenerator 中?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-2.2


    【解决方案1】:

    问题是您使用带有Controller 后缀的控制器名称。请把控制器名称中的Controller后缀去掉,写成如下:

    var b = _linkGenerator.GetUriByAction(HttpContext, 
        action: "GetContentByFileId", 
        controller: "File", 
        values: new { FileId = 1 }
    );
    

    现在应该可以了。

    【讨论】:

    • 这看起来很有趣。
    • 不,它不能解决它......我已经尝试过,但我现在又试了一次。 “b”再次为空。而使用 Url.Action 的“a”则不是。
    • 我已经在用了!并再次检查它。它工作得很好。
    • @MiguelMoura 我还检查了它是否仅在以Controller 后缀提及ControllerName 或找不到操作名称时才返回null。所以请再次检查bc的代码
    • @TanvirArjel 我试过你的代码,但这不是唯一的问题......我刚刚更新了这个问题。我现在知道如何解决它......不确定是否有更好的方法......有什么建议吗?
    【解决方案2】:
             app.UseEndpoints(endpoints =>
              {
                // Default route
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Account}/{action=Login}/{id?}");
               });
    
    services.AddMvc(options => options.EnableEndpointRouting = true);
    
          string url = _generator.GetUriByAction("index", "home", null, 
     _accessor.HttpContext.Request.Scheme, _accessor.HttpContext.Request.Host);
            var url1 = _generator.GetPathByAction("index", "home", 
       new { FileId = 1 });
    

    【讨论】:

    • 将应用中的默认MVC路由替换为startup.cs的configure方法中的UseEndpoints路由。
    猜你喜欢
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 2021-12-24
    • 2017-12-02
    • 1970-01-01
    相关资源
    最近更新 更多