2016-07-08 10 views
0

問題: Webクライアントを使用して別のエンドポイントにHttpPostedFileBase(メモリ上でのみ使用可能、ディスク上にはありません)を投稿できますか?私が試した何Webクライアントを使用してストリームからmultipart/form-dataファイルを投稿する

を、私は、次のコントローラを持って、私たちはフロントエンドからのファイルに掲載されており、それがファイルのパラメータにバインドします。

私は そのコントローラは、このようになります(ので、我々はクライアントから直接投稿することはできません)公に利用できない別のアプリケーションにこの要求を渡す必要があり
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です。 私は何が欠けていますか? Postmanを使用してAPIエンドポイントに直接投稿すると機能します。だから私は私のHomeControllerで何か間違っていることを推測していますか?

+0

これは他のサーバーに簡単なプロキシですか?最初のコントローラとは何ですか? MVC/WebAPI?それはWebAPIですか? – spender

+0

まあまあ、最初のコントローラはMVCコントローラで、もう1つはWebAPIコントローラです。問題を簡単に解決できるようにするには、両方のタイプを変更することができます。理想的には、私はちょうど私のAPIコントローラに直接最初の要求をパススルーしたいと思います。 – JOSEFtw

答えて

1

新しい技術でこれを改善することができます。 WEBAPIで

、あなたはこのようなコントローラのメソッド記述することができます。今、あなたはその要求を取り、そのRequestUriプロパティを書き換えることができます

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

を:HttpClientアップ

request.RequestUri = new Uri(blah); 

新しい要求を転送します:

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

sが配置された:その後、

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

response

return response; 

を返す私はあなたが必要とするため、その中にタイムアウトメカニズムが適切でない可能性があります追加しました。

+0

これは本当にうまく見える、それは働いている、一種。私のAPIから次のエラーを受け取りました '' '{ " ""リクエストURI 'http://restproxy.dev/api/files/add'に一致するHTTPリソースが見つかりませんでした。 "、 "MessageDetail": "'ファイル'というコントローラに一致するタイプが見つかりませんでした。 } '' ' ブラウザで直接そのURLにアクセスしようとするとうまくいくので、それはうまくいきます。それは私のコントローラーでやっているリクエストが間違ったアプリケーションで表示されているように感じています。どうにかして...さらに調査します! – JOSEFtw

+0

@JOSEFtw 'request.Headers.Host'プロパティも変更する必要があるようです。 – spender

+1

うん!それはそれだった。あなたのソリューションマンに感謝、それは本当にきれいです。良い一日を! – JOSEFtw

関連する問題