6

web-api を使用して、ローカル コマンド ライン クライアントから Azure ストレージにファイルをアップロードしようとしています。そのために Azure Web サイトを使用しています。クライアントとの作業は問題ありません。そして、すべてがローカルで正常に機能しています。Web API コードは次のとおりです。

    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 に Web サイトをデプロイするとすぐにアップロードできません。これは、Azure Web サイトが LocalResource にアクセスできないためです。そして、Azure Web ロールに切り替える必要があります。切り替えることはできますが、ローカル ファイル システムにアクセスするのが面倒です。

また、MultipartFormDataStreamProvider() のインスタンスには LocalResource が必要です。また、ファイルを WebApi にアップロードする別の方法は見つかりませんでした。私の計画は、ローカル HDD に何も保存せずに、Azure に直接アップロードすることでした。

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

psクライアント アプリケーションに署名付きの URL を提供し、クライアントが Azure ブログに直接アップロードできるShared Access Signatures の使用法を見てきました。しかし、それがどれほど安全であるかについては確信が持てず、署名をクライアントに渡すことに (まだ) 満足しているとは言えません。現時点では、クライアントは非常に敵対的な環境で実行され、クライアントから戻ってくるものは何も信頼できないと思います.

UPD私の最終的な解決策は、サーバーで発行され、クライアントに渡される書き込み専用のShared Access Signatureを使用することでした。その後、クライアントはファイルを Azure に直接アップロードします。このようにして、アップロードされたファイルを管理する手間を大幅に省くことができます。そして、ここに私のソリューションのより詳細な説明があります。

4

3 に答える 3

2

ファイルが最初にローカルに保存されず、AWSStream に直接書き込まれるように、MultipartFormDataStreamProvider をオーバーライドするこの StackOverflow 記事を見つけました。参照: MultipartFormDataStreamProvider をオーバーライドして、アップロードをファイル システムに保存しないようにすることは可能ですか?

しかし、トレイルマックスのソリューションも気に入っていると言わざるを得ません。

于 2013-11-02T21:09:52.173 に答える
1

コードを LocalResource でそのまま動作させるための解決策の 1 つは、Owin を介して Web API を自己ホストするワーカー プロセス内でこれをホストすることです。

http://www.asp.net/web-api/overview/hosting-aspnet-web-api/host-aspnet-web-api-in-an-azure-worker-roleで簡単なチュートリアルを見つけることができます。

RoleEntryPoint の OnStart() メソッド内で Owin がホストする API を起動するだけです。Web API 応答から Html を返すこともできるため、worker ロールを非常に柔軟な基本プロジェクトにすることができます。

上記のリンクから Owin ホストをセットアップする方法を示す簡単なスニペットを次に示します。

private IDisposable _webApp = null;

public override bool OnStart() {
   ServicePointManager.DefaultConnectionLimit = 5;

   var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["DefaultEndpoint"];
   var baseUri = string.Format("{0}://{1}", endpoint.Protocol, endpoint.IPEndpoint);

   _webApp = WebApp.Start<Startup>(new StartOptions(baseUri));

   return base.OnStart();
}

public override void OnStop() {
    if (_webApp != null) {
        _webApp.Dispose();
    }
    base.OnStop();
}

...

using System.Web.Http;
using Owin;

class Startup {
    public void Configuration(IAppBuilder app) {
        var config = new HttpConfiguration();

        config.Routes.MapHttpRoutes("Default", "{controller}/{id}",
                                    new { id = RouteParameter.Optional });

        app.UseWebApi(config);

    }
}
于 2013-07-19T20:42:14.940 に答える