简体   繁体   English

在ASP.NET MVC中将文件从控制器发送到远程ApiController的通用有效方法

[英]Generic and efficient way to send files from a Controller to remote ApiController in ASP.NET MVC

I am working on a multi-level ASP.NET MVC web platform and I have the requirement to send a file from a System.Web.Mvc.Controller to an ASP.NET MVC web-service's System.Web.Http.ApiController , running remotely on a different machine. 我正在使用多级ASP.NET MVC Web平台,并且需要将文件从System.Web.Mvc.Controller发送到ASP.NET MVC Web服务的System.Web.Http.ApiController ,并且正在运行远程在另一台计算机上。

Currently, I have this in my Mvc.Controller : 目前,我在Mvc.Controller有这个:

public ActionResult ForwardThisFile(HttpPostedFileBase file)
{
    // TODO: Forward file to remote DocumentApi:
    DocumentApi.DocumentApiClient client = new DocumentApi.DocumentApiClient();
    client.StoreDocument(file /* <-- How-To? */);
    return View();
}

where the DocumentApiClient has been generated via Visual Studio's Add REST API Client... function from a Swagger Url. 其中, DocumentApiClient是通过Swagger Url通过Visual Studio的Add REST API Client ...函数生成的。 (The generated client internally uses the Microsoft.Rest.ClientRuntime which is relying on System.Net.Http.HttpClient , HttpRequestMessage , etc.) (生成的客户端在内部使用依赖于System.Net.Http.HttpClientHttpRequestMessage等的Microsoft.Rest.ClientRuntime

The question is, how do I define and implement the DocumentApi to transfer files to it in an efficient and generic way in the ApiController . 问题是,如何在ApiController定义和实现DocumentApi以高效且通用的方式将文件传输到该文件。 Currently, I am thinking of three different options: 目前,我正在考虑三种不同的选择:

  • [HttpPut] public async Task<IHttpActionResult> StoreDocument(HttpPostedFileBase file)
  • [HttpPut] public async Task<IHttpActionResult> StoreDocument(byte[] fileContents, string contentType, string fileName)
  • [HttpPut] public async Task<IHttpActionResult> StoreDocument(Stream fileStream, string contentType, string fileName)

I was thinking, that maybe I could just forward the HttpPostedFileBase instance from the Mvc.Controller to the ApiController , so I've tried the first option. 我当时在想,也许我可以将HttpPostedFileBase实例从Mvc.ControllerApiController ,所以我尝试了第一种方法。 However, Add REST API Client... creates a DocumentApi.Models.HttpPostedFileBase model class in that case and is NOT of the original type System.Web.HttpPostedFileBase . 但是,在这种情况下, 添加REST API客户端...将创建DocumentApi.Models.HttpPostedFileBase模型类,并且不是原始类型System.Web.HttpPostedFileBase Now, I'm not sure what I should do... 现在,我不确定该怎么做...

new DocumentApi.Models.HttpPostedFileBase() {
    InputStream = file.InputStream,
    ContentType = file.ContentType,
    ContentLength = file.ContentLength,
    FileName = file.FileName,
}

^ that doesn't work, because for the InputStream , it creates a DocumentApi.Models.Stream class and I have no idea how to convert the System.IO.Stream from the file parameter into a DocumentApi.Models.Stream . ^不起作用,因为对于InputStream ,它将创建一个DocumentApi.Models.Stream类,而且我不知道如何将System.IO.Streamfile参数转换为DocumentApi.Models.Stream

Is it even possible to send a stream across ASP.NET MVC webservices? 甚至可以跨ASP.NET MVC Web服务发送流吗? (Which would basically be the answer to option 3) (这基本上是选项3的答案)

In my current state of knowledge, the only alternative appears to me being option 2, where I would send a byte-array containing the whole file. 以我目前的知识状态,唯一的选择对我来说似乎是选项2,在该选项中,我将发送一个包含整个文件的字节数组。 I am asking myself, however, if there is any more convenient or more efficient way to send a file from a Mvc.Controller to a remote ApiController . 我问自己,但是,是否有任何更便捷或更有效的方法将文件从Mvc.Controller发送到远程ApiController Is there? 在那儿?
Which one of the options would work and which one is the way to go? 哪个选项可行,哪种方式可行?

Additionally, I have a bonus question to the above regarding HttpPostedFileBase : Is the way via HttpPostedFileBase the most efficient way to handle uploaded files in ASP.NET MVC? 另外,我有一个加分题以上就HttpPostedFileBase :通过方式HttpPostedFileBase来处理ASP.NET MVC上传的文件的最有效方法是什么? I have seen various alternatives: 我看到了多种选择:

  • HttpPostedFileBase like shown above in the first code sample 像上面的第一个代码示例中所示的HttpPostedFileBase
  • Using the raw HTTP-request via Request.Content.ReadAsStreamAsync() or something similar. 通过Request.Content.ReadAsStreamAsync()或类似方法使用原始HTTP请求。 Maybe the stream is more efficient for my use case? 也许对于我的用例而言,流更有效?
  • Using JavaScript to encode a file into a Base64 string and send it via a hidden input field to the controller. 使用JavaScript将文件编码为Base64字符串,然后通过隐藏的输入字段将其发送到控制器。 (via FileReader 's method readAsDataURL(file) ) (通过FileReader的方法readAsDataURL(file)

So many options... Which one is best/most generic/most efficient? 这么多的选择...哪一个是最好/最通用/最有效的?

You should use the HttpClient lib in the calling controller to async upload the file to the destination controller. 您应该在调用控制器中使用HttpClient库将文件异步上传到目标控制器。 Various examples of using HttpClient to asycn upload is here C# HttpClient 4.5 multipart/form-data upload . C#HttpClient 4.5 multipart / form-data upload是使用HttpClient进行asycn上传的各种示例。

In this case your receiving remote controller just acts as though its having a file uploaded from a browser with no specific handling required. 在这种情况下,您的接收遥控器就像从浏览器上传文件一样,而无需进行特殊处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM