2016-09-08 126 views
6

我們正在構建一個包含Angular2前端,ASP.NET Core web api公共後端和ASP.NET Core web api私人後臺。將ASP.NET Core web API中的文件發佈到另一個ASP.NET Core web api

將文件從Angular2上傳到公共後臺工作。但是我們寧願將它們發佈到私有後端。

當前工作的代碼

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

從那裏我可以使用file.CopyTo(FILESTREAM)將文件保存到磁盤;

但是,我想重新發送該文件,或這些文件,或者,理想情況下,整個請求到我的第二個web api核心。

我不知道如何用HttpClient類的asp.net核心實現這一點。

我已經試過各種東西,如

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

但我的第二後端得到一個空IFormFile。

我有一種感覺是可以將文件作爲流發送並在另一側重建它們,但無法使其工作。

該解決方案必須使用兩個web api核心。

回答

7

解決方案

在DMZ公共後端

[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 
    } 
} 

私人後端

[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); 
      }     
     } 
    }   
} 
0

當您調用私有後端API時忽略HttpClient,您是否可以從公共Core API項目引用私有Core API項目並直接從Core API項目調用控制器?看到請求仍然爲空/空。如果請求帶有值,那麼問題是使用HttpClient。

理想情況下,您希望爲要分發給使用客戶端的私有Core API創建一個包庫(一種SDK)。這就像一個包裝/代理。通過這種方式,您可以隔離私有後端系統,並且可以單獨對其進行故障排除。所以你公開的Core API項目(這是私人後端客戶端)可以引用它作爲nuget包。

1

嗨,我有同樣的問題,這是對我工作:

我的設置是netCore MVC netCoreApi。

我的MVC控制器看起來像:

[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的方法:

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); 
     } 
    } 

而且至少我的WebAPI控制器:

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

在這裏看到完整的代碼是我RESTClient實現郵政方法:

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; 
     } 
    } 

//啊,我知道我不是讓HttpStatusCode.Created回;)

編碼快樂;)

相關問題