2016-07-08 44 views
0

問題:是否有可能使用Web客戶端將HttpPostedFileBase(僅在內存中,而不是在磁盤上)發佈到另一個端點?從Web客戶端流發佈多部分/表格數據文件

我已經試過什麼:

我有以下的控制器,我們從我們的前端文件發佈,並將其綁定到文件的參數。

public class HomeController : Controller 
{ 
    [System.Web.Http.HttpPost] 
    public async Task<string> Index(HttpPostedFileBase file) 
    { 
     //file is not null here, everything works as it should. 

     //Here im preparing a multipart/form-data request to my api endpoint 
     var fileStreamContent = new StreamContent(file.InputStream); 
     using (var client = new HttpClient()) 
     using (var formData = new MultipartFormDataContent()) 
     { 
      formData.Add(fileStreamContent); 
      var response = await client.PostAsync("http://restapi.dev/api/files/add", formData); 
      var result = await response.Content.ReadAsStringAsync(); 
      return result; 
     } 
    } 
} 

我需要傳遞到另一個應用程序,這不是公開提供該請求(因此我們不能直接從客戶端發佈) 該控制器是這樣的:

[RoutePrefix("api/files")] 
public class FilesController : ApiController 
{ 
    [HttpPost] 
    [Route("add")] 
    public async Task<HttpResponseMessage> Add(HttpPostedFileBase file) 
    { 
     //This is the problem, file is always null when I post from my backend. 
     var files = HttpContext.Current.Request.Files.Count > 0 ? HttpContext.Current.Request.Files[0] : null; 
     return Request.CreateResponse(HttpStatusCode.OK); 
    } 
} 

file總是null,所以files。 我錯過了什麼?當我使用郵遞員並直接發佈到API端點時,它可以工作。所以即時猜測,即時通訊在我的HomeController做錯了什麼?

+0

所以這是一個簡單的代理到另一臺服務器上?第一個控制器是什麼? MVC/WebAPI?它可能是WebAPI嗎? – spender

+0

是的,第一個控制器是MVC控制器,第二個控制器是WebAPI控制器。如果這樣可以更容易地解決問題,我可以改變它們的類型。理想情況下,我只想直接向我的api控制器傳遞第一個請求。 – JOSEFtw

回答

1

你可以用更新的技術來改善這一點。

在的WebAPI,你可以寫一個控制器的方法是這樣的:

//[Route("api/Foo")] //maybe? 
[HttpPost] 
public async Task<HttpResponseMessage> MyResourceProxy(HttpRequestMessage request) 

現在你可以把這個請求並重寫其RequestUri屬性:

request.RequestUri = new Uri(blah); 

新建立一個HttpClient和轉發請求:

HttpClient client = new HttpClient(); 
//make sure that this fails if it's hung for more than 30 seconds 
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); 
try 
{ 
    response = await client.SendAsync(request, 
             HttpCompletionOption.ResponseHeadersRead, 
             cts.Token); 
} 
catch (TaskCanceledException) 
{ 
    response = new HttpResponseMessage(HttpStatusCode.GatewayTimeout); 
} 

確保所有東西都得到Š配置:

request.RegisterForDispose(new IDisposable[] {request, client, cts, response}); 

,然後返回response

return response; 

我說你需要一個超時機制可能是不合適的。

+0

這看起來非常好,它工作,有點。我收到以下錯誤(來自我的api) '''{ 「消息」:「沒有找到與請求URI相匹配的HTTP資源http://restproxy.dev/api/files/add'。」, 「MessageDetail」:「找不到與名爲'files'的控制器匹配的類型。」 }''' 這很奇怪,因爲如果我嘗試直接在瀏覽器中訪問該URL,它就會起作用。感覺好像在我的控制器中執行的請求看起來在錯誤的應用程序中,不知何故...將進一步調查! – JOSEFtw

+0

@JOSEFtw它看起來像你可能還需要更改'request.Headers.Host'屬性。 – spender

+1

是的!就是這樣。謝謝你的解決方案的人,它真的很乾淨。祝你今天愉快! – JOSEFtw