.NET Core将本地API表单数据发布请求转发到远程API [英] .NET Core forward a local API form-data post request to remote API

查看:885
本文介绍了.NET Core将本地API表单数据发布请求转发到远程API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个AJAX表单,该表单将表单数据发布到本地API URL: / api / document 。它包含一个文件和一个自定义ID。我们只是想接收确切的请求并将其转发到位于 example.com:8000/document/upload 的远程API。

I have an AJAX form which post a form-data to a local API url: /api/document. It contains a file and a custom Id. We simply want to take the exact received Request and forward it to a remote API at example.com:8000/document/upload.

是否有一种简单的方法可以使用Asp.NET Core将请求转发(或代理?)到远程API?

Is there a simple way of achieve this "forward" (or proxy?) of the Request to a remote API using Asp.NET Core?

下面我们有一个想法,就是简单地使用Web API Http客户端来获取请求,然后重新发送请求(这样做例如,我们希望能够从后端附加一个私有api密钥),但是似乎无法正常工作, PostAsync 不接受 Request

Below we had the idea to simply use Web API Http client to get the request and then resend it (by doing so we want to be able to for example append a private api key from the backend), but it seems not to work properly, the PostAsync doesn't accept the Request.

POST http://localhost:62640/api/document HTTP/1.1
Host: localhost:62640
Connection: keep-alive
Content-Length: 77424
Accept: application/json
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryn1BS5IFplQcUklyt
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8,fr;q=0.6

------WebKitFormBoundaryn1BS5IFplQcUklyt
Content-Disposition: form-data; name="fileToUpload"; filename="test-document.pdf"
Content-Type: application/pdf
...
------WebKitFormBoundaryn1BS5IFplQcUklyt
Content-Disposition: form-data; name="id"

someid
------WebKitFormBoundaryn1BS5IFplQcUklyt--



后端代码



我们的.NET Core后端具有简单的转发到另一个API目的。

Backend Code

Our .NET Core backend has a simple "forward to another API" purpose.

public class DocumentUploadResult
{
     public int errorCode;
     public string docId;
}

[Route("api/[controller]")]
public class DocumentController : Controller
{
    // POST api/document
    [HttpPost]
    public async Task<DocumentUploadResult> Post()
    {
        client.BaseAddress = new Uri("http://example.com:8000");

        client.DefaultRequestHeaders.Accept.Clear();
        HttpResponseMessage response = await client.PostAsync("/document/upload", Request.Form);
        if (response.IsSuccessStatusCode)
        {
            retValue = await response.Content.ReadAsAsync<DocumentUploadResult>();
        }
        return retValue;
    }
}

我们有一个GET请求(此处未转载)效果很好。因为它不必从本地发布的数据中获取数据。

We have a GET request (not reproduced here) which works just fine. As it doesn't have to fetch data from locally POSTed data.

如何只是传递传入的本地HttpPost请求并将其转发到远程API?

我在stackoverflow或网络上搜索了很多,但都是旧资源谈论转发 Request.Content 到远程。

I searched A LOT on stackoverflow or on the web but all are old resources talking about forwarding Request.Content to the remote.

但是在Asp.NET Core 1.0中,我们无权访问 Content 。我们只能检索 Request.Form (也不能检索 Request.Body ),然后将其不接受为 PostAsync 方法:

But on Asp.NET Core 1.0, we don't have access to Content. We only are able to retrieve Request.Form (nor Request.Body) which is then not accepted as an argument of PostAsync method:


无法从Microsoft.AspNetCore.Http.IformCollection转换为
System.Net.Http.HttpContent

Cannot convert from Microsoft.AspNetCore.Http.IformCollection to System.Net.Http.HttpContent

我有直接将请求传递给postAsync的想法:

I had the idea to directly pass the request to the postAsync:


无法从Microsoft.AspNetCore.Http.HttpRequest转换为
System.Net.Http.HttpContent

Cannot convert from Microsoft.AspNetCore.Http.HttpRequest to System.Net.Http.HttpContent

我不知道如何从收到的本地请求中重建预期的 HttpContent

I don't know how to rebuild expected HttpContent from the local request I receive.

有关信息,当我们使用自定义的<$ c $发布有效的表单数据时c> Id 和上传的文件,远程(example.com)API响应为:

For information, When we post a valid form-data with the custom Id and the uploaded file, the remote (example.com) API response is:

{
  "errorCode": 0
  "docId": "585846a1afe8ad12e46a4e60"
}


推荐答案

好,首先创建一个视图模型来保存表单信息。由于涉及文件上传,因此在模型中包括 IFormFile

Ok first create a view model to hold form information. Since file upload is involved, include IFormFile in the model.

public class FormData {
    public int id { get; set; }
    public IFormFile fileToUpload { get; set; }
}

模型绑定器应选择类型并使用传入的模型填充模型数据。

The model binder should pick up the types and populate the model with the incoming data.

通过将内容复制到新请求来更新控制器操作以接受模型并代理数据转发。

Update controller action to accept the model and proxy the data forward by copying content to new request.

[Route("api/[controller]")]
public class DocumentController : Controller {
    // POST api/document
    [HttpPost]
    public async Task<IActionResult> Post(FormData formData) {
        if(formData != null && ModelState.IsValid) {
            client.BaseAddress = new Uri("http://example.com:8000");
            client.DefaultRequestHeaders.Accept.Clear();

            var multiContent = new MultipartFormDataContent();

            var file = formData.fileToUpload;
            if(file != null) {
                var fileStreamContent = new StreamContent(file.OpenReadStream());
                multiContent.Add(fileStreamContent, "fileToUpload", file.FileName);
            }

            multiContent.Add(new StringContent(formData.id.ToString()), "id");

            var response = await client.PostAsync("/document/upload", multiContent);
            if (response.IsSuccessStatusCode) {
               var retValue = await response.Content.ReadAsAsync<DocumentUploadResult>();
               return Ok(reyValue);
            }
        }
        //if we get this far something Failed.
        return BadRequest();
    }        
}

您可以根据需要包括必要的异常处理程序,但这是如何向前传递表单数据的最小示例。

You can include the necessary exception handlers as needed but this is a minimal example of how to pass the form data forward.

这篇关于.NET Core将本地API表单数据发布请求转发到远程API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆