2013-06-03 20 views
6

ローカルコマンドラインクライアントからweb-apiを介してAzureストレージにファイルをアップロードしようとしています。 私はそのためにAzure Web-Siteを使用しています。クライアントとの作業は問題ではありません。そして、私はすべてローカルでうまく動作しています。ここでは、ウェブAPIコードは次のとおりです。私はローカルで実行したときにローカルファイルシステムにアクセスせずにWebApi経由でAzure Blobストレージにファイルをアップロード

public async Task<HttpResponseMessage> PostUpload() 
    { 
     // need a local resource to store uploaded files temporarily 
     LocalResource localResource = null; 
     try 
     { 
      // Azure web-site fails here 
      localResource = RoleEnvironment.GetLocalResource("TempStorage"); 
     } 
     catch (Exception e) 
     { 
      return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to get access to local resources"); 
     } 

     var provider = new MultipartFormDataStreamProvider(localResource.RootPath); 

     // Read the form data. 
     await Request.Content.ReadAsMultipartAsync(provider); 

     // snipped validation code 
     var container = // code to get container 

     foreach (var fileData in provider.FileData) 
     { 
      var filename = GetBlobName(fileData); 
      var blob = container.GetBlockBlobReference(filename); 
      using (var filestream = File.OpenRead(fileData.LocalFileName)) 
      { 
       blob.UploadFromStream(filestream); 
      } 
      File.Delete(fileData.LocalFileName); 
     } 

     return Request.CreateResponse(HttpStatusCode.OK); 
    } 

すべてが正常に動作しますが、Azureのウェブサイトを持っていないので、すぐに私はアズールでウェブサイトを展開して、私は、アップロードすることはできませんLocalResourceへのアクセス。 Azure Web-Roleに切り替える必要があります。私は切り替えることができますが、ローカルファイルシステムにアクセスすることは私を一緒に気にしています。

LocalResourceは、MultipartFormDataStreamProvider()のインスタンスに必要です。そして、私はWebApiにファイルをアップロードするための代替方法を見つけられませんでした。私の計画はchannel through upload directly to Azureで、ローカルのHDDに何も保存することはありませんでした。

ファイルをアップロードする方法はありますか?

p.s.私はusages of Shared Access Signaturesを見てきました。私は、クライアントアプリケーションに署名付きのURLを与え、クライアントがAzure Blogに直接アップロードできるようにしています。しかし、私は、クライアントにシグネチャを渡すことで、どれくらい安全になるのか、それほど快適ではないのかはまだ分かりません。現時点では、クライアントは非常に敵対的な環境で実行され、クライアントから戻ってくるものは何も信頼できません。

UPD私の最終的な解決策は、サーバーで発行され、クライアントに渡された書き込みのみの共有アクセス署名を使用することでした。クライアントはAzureに直接ファイルをアップロードします。このようにして、アップロードされたファイルを管理することで多くの手間を省きます。そして、ここに私の解決のmore detailed descriptionがあります。

+0

"localResource = RoleEnvironment.GetLocalResource(" TempStorage ")" –

+0

あなたはREST APIを快適に使用できますか? –

+0

@BrianDishaw例外は、「LocalResource、System.Runtime.InteropServicesを取得できません。SEHException(0x80004005):外部コンポーネントが例外をスローしました。 "また、このページ(http://msdn.microsoft.com/en-us/library/windowsazure/ee758708.aspx)では、ローカルリソースはWebおよびWebサイトではなく、ワーカーの役割 – trailmax

答えて

11

これは正確な答えではありませんが、MultiPartFileStreamProviderとPath.GetTempPath()を使用してAzure Webサイトでローカルストレージを使用できます。コードはLocalResourceがOwin経由でワーカープロセスの自己ホストのWeb APIのこの内部をホストすることであろうと、あなたのコードがあるとして動作させるために、この

public async Task<HttpResponseMessage> PostUpload() 
{ 
    var provider = new MultipartFileStreamProvider(Path.GetTempPath()); 

    // Read the form data. 
    await Request.Content.ReadAsMultipartAsync(provider); 

    // do the rest the same  
} 
+0

今、私はAzureがどのようにWebサイトのTempPath()を管理しているのか、それがどれほど信頼できるのだろうと思います。大きなファイルのアップロードを途中で拭くことはできませんか? – trailmax

+0

デッドリンク、Daniel。 – Bon

+0

一時ディレクトリが一時的ではないことを示す無効なリンクを削除しました。私の知る限り、これはまだ真実です。 –

1

一つの可能​​な解決策のようになります。あなただけRoleEntryPointののOnStart()メソッド内でOwinでホストされているAPIを起動する必要がhttp://www.asp.net/web-api/overview/hosting-aspnet-web-api/host-aspnet-web-api-in-an-azure-worker-role

あなたは、簡単なチュートリアルを見つけることができます。また、Web APIの応答からHtmlを返すことができるので、ワーカーロールを非常に柔軟な基本プロジェクトにすることができます。ファイルを最初にローカルに保存されているが、直接に書き込まれないように、私はMultipartFormDataStreamProviderを上書きし、このStackOverflowの記事を見つけました

+0

Webロールにサイトを展開し、LocalResourceを利用できるようになりました。 web-apiだけをワーカーロールにデプロイすることは過度のことです。とにかく、私は問題を、blobストレージに書き込み専用のShared Access Signatureを発行し、WebApi経由でクライアントに渡して解決しました。そしてクライアントはファイルをAzureに直接アップロードします。 – trailmax

関連する問題