c# - 将所有 POST 请求路由到 1 个接收 POST 正文的 APIController 方法
问题描述
我试图在我的 ApiController 中配置一个方法来处理所有 POST 请求,无论路径段的数量如何,并接收始终为 json 的 post 正文。我已经尝试了几种通配符表和属性路由的变体,但无法使其适用于具有超过 1 个路径段的请求。
另外,我不知道如何在方法中接收整个 json 主体。
[RoutePrefix("api")]
public class MyController: ApiController
{
[HttpPost]
[Route("*")]
public string PostHandler([FromBody]string jsonBody)
{
var requestPath = Request.RequestUri.LocalPath;
return jsonBody;
}
}
解决方案
尝试在 [Route()] 中使用正则表达式通配符并且不要指定 [RoutePrefix]。还可以尝试直接从请求中获取正文作为字符串,这应该可以。
public class MyController: ApiController
{
[HttpPost]
[Route("api/{*[a-zA-Z]}")]
public string PostHandler()
{
string result = Request.Content.ReadAsStringAsync().Result;
var requestPath = Request.RequestUri.LocalPath;
return result;
}
}
如果您想使用异步,请尝试以下代码:
public class MyController: ApiController
{
[HttpPost]
[Route("api/{*[a-zA-Z]}")]
public async Task<string> PostHandler()
{
string result = await Request.Content.ReadAsStringAsync();
var requestPath = Request.RequestUri.LocalPath;
return result;
}
}
编辑
在[Route("api/{*asd}")]
该{*[a-zA-Z]}
部分不做任何事情,而是 MVC 堆栈使用正则表达式验证每个路由:
{(?<parameterName>.+?)(:(?<constraint>.*?(\(.*?\))?))*(?<defaultValue>\?|(=.*?))?}
使用这个工具,我发现 [a-zA-Z] 是 parameterName 组的一部分,并被用作将值注入到动作参数中。
如果我们使用
public class MyController: ApiController
{
[HttpPost]
[Route("api/{*path}")]
public string PostHandler(string path)
{
string result = Request.Content.ReadAsStringAsync().Result;
var requestPath = Request.RequestUri.LocalPath;
return result;
}
}
并调用 /api/user/123/orders/100,然后:
path = "user/123/orders/100"
requestPath = "/api/user/123/orders/100"
推荐阅读
- graphql - GraphQL 查询以根据内容 Web 应用程序中的顺序对引用进行排序
- javascript - Babel-CLI 正确设置配置值
- perl - Perl - 在 cp1251 中复制到剪贴板
- mysql - MySql InnoDB 表更新单行需要 1+ 秒
- c# - 如果是另一个具有相同名称的表单打开 C#,则关闭表单
- python - 在这种情况下,我需要树数据类型吗?[井字游戏]
- node.js - curl 中的“troute=t1”cookie 设置是什么?以及如何在 NodeJS 中模拟它
- node.js - 是否可以将 Firestore 查询表示为字符串
- windows - 在 cmake 中获取 Windows 可执行文件的运行时依赖项并安装它们
- google-sheets - 如何修改 Google 表格中重复条目的值