【问题标题】:C# POSTing [FromBody] data from one controller to anotherC# 将 [FromBody] 数据从一个控制器发送到另一个控制器
【发布时间】:2016-01-16 01:17:51
【问题描述】:

是否可以使用client.GetAsync()(或 PostAsync/SendAsync)将[FromBody] POST 数据发送到控制器?

我必须设置一个所有 api 调用都会通过的基本控制器。

我的 ajax 调用都转到这个 SecureApi 控制器,它们将原始路径作为参数发送给它们可以重新路由到正确的控制器。比如:

$.ajax({
    url: "./api/SecureApi/?path=/api/OtherApi/SomeRoute",
    data: {
        param1: 1,
        param2: 2
    }
});

所以我的基本控制器看起来像:

public class SecurityApiController : ApiController
{
    [HttpPost]
    public HttpResponseMessage SecureApi([FromBody]object data, string path)
    {
        // do some stuff

        // get uri
        var applicationPath = Request.RequestUri.Scheme + "://" + Request.GetRequestContext().VirtualPathRoot.Replace("/", String.Empty);
        Uri routeUri = new Uri(applicationPath + path);

        // then redirect to correct controller
        var config = new HttpConfiguration();
        var server = new HttpServer(config);
        var client = new HttpClient(server);
        // how can I send [FromBody]object data here?
        var response = client.GetAsync(routeUri).Result; // or PostAsync/SendAsync?
        return response;
    }
}

other 控制器看起来像:

public class OtherApiController : ApiController
{
    [HttpPost]
    public HttpResponseMessage OtherApi([FromBody]OtherData data)
    {
        // do stuff
    }
}

很遗憾,我无法更改OtherApi,所以我必须以相同的方式(在 POST 正文中)发送[FromBody] POST 数据。

这可能吗?

编辑:

根据@Philippe 在下面的回复,我正在使用 PostAsJsonAsync,它似乎想要工作,但我得到了 401 Unauthorized 结果。更多信息:

我选择了正确的(?)ASYNC/AWAIT 路线...

public async Task<HttpResponseMessage> SecureApi([FromBody]Dictionary<string, dynamic> data, string path)
{
    ...
    var client = new HttpClient();
    var response = await client.PostAsJsonAsync(routePath, data);
    return response;
}

Other 控制器有:

[Authorize(Roles = "Admin")] // I do have the "Admin" role
[Route("Save")]
[HttpPost]
public SaveResultBase Save([FromBody]Dictionary<string, dynamic> data)
{
    ...
}

但是这个控制器永远不会被命中(没有断点被命中)并且它返回一个 401 Unauthorized 响应。

我想我必须在调用PostAsJsonAsync 之前将我的用户凭据添加到客户端标头。但是找不到任何方法。

【问题讨论】:

    标签: c# asp.net ajax asp.net-mvc asp.net-ajax


    【解决方案1】:

    HttpClient 的 GetAsync 方法将发送一个 HTTP GET 请求,因此只能有 [FromUri] 参数。因为[FromBody] 参数根据定义是 POST 数据,所以您需要使用 PostAsJsonAsync/PostAsXmlAsync/PostAsync。它们之间的区别在于数据的序列化方式。

    var response = client.PostAsJsonAsync(routeUri, data).Result;
    

    话虽如此,如果您考虑到安全性,那么任何人都可以很容易地直接调用“正确的 api”。此外,您将通过生成两个 HTTP 请求来增加延迟。

    您应该查看 MSDN 上的 this guide。我相信authentication filter 可能是您正在寻找的。

    【讨论】:

    • 谢谢!我们确实使用用户身份验证和身份验证过滤,但我们希望能够在我们的标准 API 调用上使用 AES 加密,这样它就不会轻易暴露给用户。不确定这是不是最好的方法,但这是我们想出的。绝对可以接受其他建议。 (我将尝试 PostAsJsonAsync 并在我开始工作时将其标记为“答案”)。
    • 我在顶部的“编辑”下添加了更多信息
    • @dmathisen 这个实现的主要问题是你要么阻止路由到你的其他 API,所以你确定它们不能被直接调用(但在这种情况下你阻止了你自己的连接以及)或者您让标准路由(并且安全 API 变得无用,因为任何人都可以通过查看 URL 获得直接地址)。关于您的 401 错误,我很确定您有这个问题,因为服务器不认为 SecureAPI 与“真实”客户端的用户相同......可能有一种方法可以设置 HTTPClient 的 cookie 容器客户...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    相关资源
    最近更新 更多