在 Razor Pages 应用程序中获取 url 到 web api 控制器方法?
Get url to web api controller method in the Razor Pages app?
我在 /Pages 文件夹下有 index.cshtml。和同一文件夹中的网络 api 控制器:
[Route("api/[controller]")]
[ApiController]
public class ValuesController: ControllerBase
{
[HttpGet]
public IEnumerable<string> GetValue(){
return new string[] { "value1", "value2" };
}
}
现在我希望这段代码可以工作(因为它在 Asp Core 2 中工作):
var apiUri = Url.Action(action: "GetValue", controller: "Values");
var apiUri2 = Url.ActionLink(action: "GetValue", controller: "Values");
但它不起作用(return 空值)!以及我尝试过的所有其他选项:
var apiUri3 = Url.Action(action: "GetValue", controller: "ValuesController");
如何在 CORE 3(4 和 5)中强制 Url.Action
为 Web api 控制器工作?
这是 IActionDescriptorCollectionProvider.ActionDescriptors.Items
信息:
项目结构(实际上是核心网络应用程序):
命令window结果:
>? Url.Action(action: "GetValue", controller: "Values");
null
>? Url.Action(action: "GetValue", controller: "ValuesController");
null
>? Url.Action(action: "Value", controller: "ValuesController");
null
>? Url.Action(action: "Value", controller: "Values");
null
>
对于那些减去“明显”(我猜)的人,自己测试一下:
- [ApiController] 注释掉(控制器未标记为 ApiController); [Route("api/[controller]/[action]")] 添加;没有端点。* 修改 - 控制器是“可路由的”吗? (回答“否”)
- 仍然不是 [ApiController] 但现在我们添加 endpoints.MapControllerRoute("default", "api/[controller]/[action]"); - 控制器是“可路由的”吗? (回答“是”)
- 现在我们另外要 (2) 注释掉 [Route("api/[controller]/[action]")] - 控制器是“可路由的”吗? (回答“否”)
- 现在 return [Route("api/[area]/[controller]/[action]")] 但还要添加 [ApiController] 并添加 [Area("myarea") ] 控制器是“可路由的”吗? (回答“否”)
它不起作用的原因是 Api控制器的路由不同。
在你的例子中:
[Route("api/[controller]")]
[ApiController]
public class ValuesController: ControllerBase
{
[HttpGet]
public IEnumerable<string> GetValue(){
return new string[] { "value1", "value2" };
}
}
假设这在本地主机
真正的意思是路由是“http:///localhost/api/Values”
如果你想要例如“http://localhost/api/Values/GetValue”,你需要这样做:
[Route("api/[controller]")]
[ApiController]
public class ValuesController: ControllerBase
{
[HttpGet("GetValue")]//notice the extra piece of route we added here
public IEnumerable<string> GetValue()
{
return new string[] { "value1", "value2" };
}
[HttpGet("GetAnotherValue")]//notice the extra piece of route we added here
public IEnumerable<string> GetValue()
{
return new string[] { "value1", "value2" };
}
}
至于使用 Url.Action 你可能会使用类似的东西:
///api/Values/GetValue"
var apiUri1 = Url.Action(action: "GetValue", controller: "Values");
///api/Values/GetAnotherValue"
var apiUri2 = Url.Action(action: "GetAnotherValue", controller: "Values");
最后你需要确保映射了 api 控制器路由
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Map attribute-routed API controllers
//endpoints.MapDefaultControllerRoute(); // Map conventional MVC controllers using the default route
endpoints.MapRazorPages();//map razor pages
});
最后,您的“ApiController”控制器不需要位于“Pages”文件夹中。
Api 控制器按属性而不是“文件夹位置”路由。我建议您将它们放在项目根目录中名为 Controllers 的文件夹中。
这个 post 中的另一个答案似乎“有效”,但是一旦您向 API 控制器添加另一个操作,您就会意识到它在 [=34] 上产生了错误的 url =] 调用,因为在 Api 控制器中,路由不会通过“方法名称”发生
我在 /Pages 文件夹下有 index.cshtml。和同一文件夹中的网络 api 控制器:
[Route("api/[controller]")]
[ApiController]
public class ValuesController: ControllerBase
{
[HttpGet]
public IEnumerable<string> GetValue(){
return new string[] { "value1", "value2" };
}
}
现在我希望这段代码可以工作(因为它在 Asp Core 2 中工作):
var apiUri = Url.Action(action: "GetValue", controller: "Values");
var apiUri2 = Url.ActionLink(action: "GetValue", controller: "Values");
但它不起作用(return 空值)!以及我尝试过的所有其他选项:
var apiUri3 = Url.Action(action: "GetValue", controller: "ValuesController");
如何在 CORE 3(4 和 5)中强制 Url.Action
为 Web api 控制器工作?
这是 IActionDescriptorCollectionProvider.ActionDescriptors.Items
信息:
项目结构(实际上是核心网络应用程序):
命令window结果:
>? Url.Action(action: "GetValue", controller: "Values");
null
>? Url.Action(action: "GetValue", controller: "ValuesController");
null
>? Url.Action(action: "Value", controller: "ValuesController");
null
>? Url.Action(action: "Value", controller: "Values");
null
>
对于那些减去“明显”(我猜)的人,自己测试一下:
- [ApiController] 注释掉(控制器未标记为 ApiController); [Route("api/[controller]/[action]")] 添加;没有端点。* 修改 - 控制器是“可路由的”吗? (回答“否”)
- 仍然不是 [ApiController] 但现在我们添加 endpoints.MapControllerRoute("default", "api/[controller]/[action]"); - 控制器是“可路由的”吗? (回答“是”)
- 现在我们另外要 (2) 注释掉 [Route("api/[controller]/[action]")] - 控制器是“可路由的”吗? (回答“否”)
- 现在 return [Route("api/[area]/[controller]/[action]")] 但还要添加 [ApiController] 并添加 [Area("myarea") ] 控制器是“可路由的”吗? (回答“否”)
它不起作用的原因是 Api控制器的路由不同。
在你的例子中:
[Route("api/[controller]")]
[ApiController]
public class ValuesController: ControllerBase
{
[HttpGet]
public IEnumerable<string> GetValue(){
return new string[] { "value1", "value2" };
}
}
假设这在本地主机
真正的意思是路由是“http:///localhost/api/Values”
如果你想要例如“http://localhost/api/Values/GetValue”,你需要这样做:
[Route("api/[controller]")]
[ApiController]
public class ValuesController: ControllerBase
{
[HttpGet("GetValue")]//notice the extra piece of route we added here
public IEnumerable<string> GetValue()
{
return new string[] { "value1", "value2" };
}
[HttpGet("GetAnotherValue")]//notice the extra piece of route we added here
public IEnumerable<string> GetValue()
{
return new string[] { "value1", "value2" };
}
}
至于使用 Url.Action 你可能会使用类似的东西:
///api/Values/GetValue"
var apiUri1 = Url.Action(action: "GetValue", controller: "Values");
///api/Values/GetAnotherValue"
var apiUri2 = Url.Action(action: "GetAnotherValue", controller: "Values");
最后你需要确保映射了 api 控制器路由
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Map attribute-routed API controllers
//endpoints.MapDefaultControllerRoute(); // Map conventional MVC controllers using the default route
endpoints.MapRazorPages();//map razor pages
});
最后,您的“ApiController”控制器不需要位于“Pages”文件夹中。 Api 控制器按属性而不是“文件夹位置”路由。我建议您将它们放在项目根目录中名为 Controllers 的文件夹中。
这个 post 中的另一个答案似乎“有效”,但是一旦您向 API 控制器添加另一个操作,您就会意识到它在 [=34] 上产生了错误的 url =] 调用,因为在 Api 控制器中,路由不会通过“方法名称”发生