9

現在、アップロード中のファイルを WebAPI コントローラーに保存できますが、正しく表示できるように、ファイルを正しいファイル名拡張子の GUID として保存できるようにしたいと考えています。

コード:

 [ValidationFilter]
    public HttpResponseMessage UploadFile([FromUri]string AdditionalInformation)
    {
        var task = this.Request.Content.ReadAsStreamAsync();
        task.Wait();

        using (var requestStream = task.Result)
        {
            try
            {
                // how can I get the file extension of the content and append this to the file path below?

                using (var fileStream = File.Create(HttpContext.Current.Server.MapPath("~/" + Guid.NewGuid().ToString())))
                {
                    requestStream.CopyTo(fileStream);
                }
            }
            catch (IOException)
            {                    
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
        }

        HttpResponseMessage response = new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.Created;
        return response;
    }

コンテンツの実際のファイル名を把握できないようです。headers.ContentDisposition.FileNameが候補かもしれないと思いましたが、データが取り込まれていないようです。

4

1 に答える 1

19

正しい方向に私を指摘してくれた上記のコメントに感謝します。

最終的な解決策を明確にするために、ファイルを自動的にストリーミングする MultipartFormDataStreamProvider を使用しました。コードは、別の問題に投稿した別の質問にあります: MultipartFormDataStreamProvider and preserving current HttpContext

私の完全なプロバイダーコードを以下に示します。GUID ファイル名を生成する鍵は、GetLocalFileName 関数をオーバーライドし、headers.ContentDisposition プロパティを使用することです。プロバイダーは、ファイルへのコンテンツのストリーミングを処理します。

public class MyFormDataStreamProvider : MultipartFormDataStreamProvider
{
    public MyFormDataStreamProvider (string path)
        : base(path)
    { }

    public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
    {
        // restrict what images can be selected
        var extensions = new[] { "png", "gif", "jpg" };
        var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty);

        if (filename.IndexOf('.') < 0)
            return Stream.Null;

        var extension = filename.Split('.').Last();

        return extensions.Any(i => i.Equals(extension, StringComparison.InvariantCultureIgnoreCase))
                   ? base.GetStream(parent, headers)
                   : Stream.Null;

    }

    public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
    {
        // override the filename which is stored by the provider (by default is bodypart_x)
        string oldfileName = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
        string newFileName = Guid.NewGuid().ToString() + Path.GetExtension(oldfileName);

        return newFileName;       
    }
}
于 2013-06-03T20:33:02.437 に答える