将所有POST请求路由到1个接收POST正文的APIController方法

时间:2018-09-11 15:56:37

标签: c# asp.net-web-api asp.net-apicontroller

我试图在我的ApiController中配置一个方法来处理所有POST请求,而不管路径段的数量如何,并接收始终为json的帖子主体。我已经尝试了通配符表和属性路由的几种变体,但无法使其用于具有1个以上路径段的请求。

此外,我不知道如何在方法中接收整个json主体。

{{1}}

1 个答案:

答案 0 :(得分:1)

请尝试在[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;
    }
} 

EDIT

[Route("api/{*asd}")]中,{*[a-zA-Z]}并没有做任何事情,而是MVC堆栈使用正则表达式验证了每条路由:

{(?<parameterName>.+?)(:(?<constraint>.*?(\(.*?\))?))*(?<defaultValue>\?|(=.*?))?}  

我使用this工具发现[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"