LinkGenerator returns NULL Url 而 Url.Action 没有...为什么
LinkGenerator returns NULL Url while Url.Action doesn't ... Why
在 ASP.NET Core 2.2 控制器上,我尝试以 3 种方式生成 Link:
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我得到了正确的link ...
在 "b" 和 "c" 中我得到 null 并且我提供相同的数据......我想。
我正在控制器中注入 Link生成器,它不为空 ...
我也在注入 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 回答的 Controller 后缀之外,我能够指出问题所在。
如果我注释以下代码行,所有网址都是正确的:
[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;
});
然后 url 变为 null ...
这个 ApiVersion 添加的是 "v1.0" 在文件之前所以它变成了 "v1.0/files".
所以link生成器应该变成:
var b = _linkGenerator.GetUriByAction(HttpContext,
action: "GetContentByFileId",
controller: "File",
values: new { apiVersion = "1.0", fileId = 1
});
问题
有没有办法在不指定的情况下将 apiVersion 集成到 LinkGenerator 中?
问题是您使用的控制器名称带有 Controller
后缀。请去掉控制器名称的Controller
后缀,写成如下:
var b = _linkGenerator.GetUriByAction(HttpContext,
action: "GetContentByFileId",
controller: "File",
values: new { FileId = 1 }
);
现在应该可以了。
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 });
在 ASP.NET Core 2.2 控制器上,我尝试以 3 种方式生成 Link:
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我得到了正确的link ...
在 "b" 和 "c" 中我得到 null 并且我提供相同的数据......我想。
我正在控制器中注入 Link生成器,它不为空 ...
我也在注入 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 回答的 Controller 后缀之外,我能够指出问题所在。
如果我注释以下代码行,所有网址都是正确的:
[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;
});
然后 url 变为 null ...
这个 ApiVersion 添加的是 "v1.0" 在文件之前所以它变成了 "v1.0/files".
所以link生成器应该变成:
var b = _linkGenerator.GetUriByAction(HttpContext,
action: "GetContentByFileId",
controller: "File",
values: new { apiVersion = "1.0", fileId = 1
});
问题
有没有办法在不指定的情况下将 apiVersion 集成到 LinkGenerator 中?
问题是您使用的控制器名称带有 Controller
后缀。请去掉控制器名称的Controller
后缀,写成如下:
var b = _linkGenerator.GetUriByAction(HttpContext,
action: "GetContentByFileId",
controller: "File",
values: new { FileId = 1 }
);
现在应该可以了。
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 });