Mail files from ASP.NET Core web api to another ASP.NET Core web api

We are creating a web application consisting of the Angular2 interface, ASP.NET Core web api and the ASP.NET Core web api backend.

Uploading files from Angular2 to the common backend. But we would prefer to publish them on a private backend.

Current working code

[HttpPost] public StatusCodeResult Post(IFormFile file) { ... } 

From there, I can save the file to disk using file.CopyTo (fileStream);

However, I want to resubmit this file or these files or, ideally, the entire request to my second api web server.

I am not sure how to achieve this with the asp.net core HttpClient class.

I tried all kinds of things like

 StreamContent ss = new StreamContent(HttpContext.Request.Body); var result = client.PostAsync("api/Values", ss).Result; 

But my second backend gets an empty IFormFile.

I have a feeling that you can send a file as a stream and restore it on the other hand, but cannot make it work.

The solution should use two web api kernels.

+8
source share
4 answers

Decision

DMZ public backend

 [HttpPost] public StatusCodeResult Post(IFormFile file) { try { if (file != null && file.Length > 0) { using (var client = new HttpClient()) { try { client.BaseAddress = new Uri(currentPrivateBackendAddress); byte[] data; using (var br = new BinaryReader(file.OpenReadStream())) data = br.ReadBytes((int)file.OpenReadStream().Length); ByteArrayContent bytes = new ByteArrayContent(data); MultipartFormDataContent multiContent = new MultipartFormDataContent(); multiContent.Add(bytes, "file", file.FileName); var result = client.PostAsync("api/Values", multiContent).Result; return StatusCode((int)result.StatusCode); //201 Created the request has been fulfilled, resulting in the creation of a new resource. } catch (Exception) { return StatusCode(500); // 500 is generic server error } } } return StatusCode(400); // 400 is bad request } catch (Exception) { return StatusCode(500); // 500 is generic server error } } 

Private backend

 [HttpPost] public void Post() { //Stream bodyStream = HttpContext.Request.Body; if (Request.HasFormContentType) { var form = Request.Form; foreach (var formFile in form.Files) { var targetDirectory = Path.Combine(_appEnvironment.WebRootPath, "uploads"); var fileName = GetFileName(formFile); var savePath = Path.Combine(targetDirectory, fileName); using (var fileStream = new FileStream(savePath, FileMode.Create)) { formFile.CopyTo(fileStream); } } } } 
+12
source

Hi, I had the same problem and it helped me:

My setup is netCore MVC netCoreApi.

My MVC controller looks like this:

 [HttpPost("UploadFiles")] public async Task<IActionResult> Post(List<IFormFile> files) { Sp4RestClient dataPovider = new Sp4RestClient("http://localhost:60077/"); long size = files.Sum(f => f.Length); foreach (var file in files) { await dataPovider.ImportFile(file); } return Ok(); } 

DataProvider Method:

 public async Task ImportFile(IFormFile file) { RestClient restClient = new RestClient(_queryBulder.BuildImportFileRequest()); using (var content = new MultipartFormDataContent()) { content.Add(new StreamContent(file.OpenReadStream()) { Headers = { ContentLength = file.Length, ContentType = new MediaTypeHeaderValue(file.ContentType) } }, "File", "FileImport"); var response = await restClient.Post<IFormFile>(content); } } 

And least my WebApi controller:

 [HttpPost] [Route("ImportData")] public IActionResult Import(IFormFile file) { return Ok(); } 

To see the full code here, my PostClient Post method:

 public async Task<RestResult<T>> Post<T>(HttpContent content) { using (HttpClient httpClient = new HttpClient()) { HttpResponseMessage response = await httpClient.PostAsync(Endpoint, content); if (response.StatusCode == HttpStatusCode.Created) { T result = JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync()); return new RestResult<T> { Result = result, ResultCode = HttpStatusCode.OK }; } RestResult<T> nonOkResult = new RestResult<T> { Result = default(T), ResultCode = response.StatusCode, Message = await response.Content.ReadAsStringAsync() }; return nonOkResult; } } 

// Yes, I know that I do not get HttpStatusCode.Created back;)

happy coding;)

+4
source

Ignoring HttpClient when calling a private API backend, can you refer to a private Core API project from a public Core API project and call the controller directly from the Core API project? See Request is still null / empty. If the request is issued with a value, then the problem is with the use of HttpClient.

Ideally, you want to create a package library (SDK view) for your private Core API that you want to distribute to consumers. It acts like a wrapper / proxy. This way you can isolate the private backend system, and you can fix it separately. Thus, you are a public Core API project (which is a private backend client) can refer to it as a nuget package.

0
source

API code

  [Route("api/upload/{id}")] [HttpPost] public async Task<IActionResult> Post(string id) { var filePath = @"D:\" + id; //+ Guid.NewGuid() + ".png"; if (Request.HasFormContentType) { var form = Request.Form; foreach (var formFile in form.Files) { if (formFile.Length > 0) { using (var stream = new FileStream(filePath, FileMode.Create)) { await formFile.CopyToAsync(stream); } } } } return Ok(new { Path = filePath }); } 

Back end

  [Route("home/UploadFile")] [HttpPost] public IActionResult UploadFile(IFormFile file) { if (file == null || file.Length == 0) return Content("file not selected"); var client = new HttpClient(); byte[] data; using (var br = new BinaryReader(file.OpenReadStream())) data = br.ReadBytes((int)file.OpenReadStream().Length); ByteArrayContent bytes = new ByteArrayContent(data); MultipartFormDataContent multiContent = new MultipartFormDataContent { { bytes, "file", file.FileName } }; var result = client.PostAsync("http://localhost:2821/api/upload/" + file.FileName, multiContent).Result; return RedirectToAction("file"); } 

Download source code

0
source

All Articles