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.
Currently, I have this in my 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. (The generated client internally uses the Microsoft.Rest.ClientRuntime
which is relying on System.Net.Http.HttpClient
, HttpRequestMessage
, etc.)
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
. 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. 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
. 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
.
Is it even possible to send a stream across ASP.NET MVC webservices? (Which would basically be the answer to option 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. 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
. 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? I have seen various alternatives:
HttpPostedFileBase
like shown above in the first code sample- Using the raw HTTP-request via
Request.Content.ReadAsStreamAsync()
or something similar. 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. (via
FileReader
's methodreadAsDataURL(file)
)
So many options... Which one is best/most generic/most efficient?