4

サーバーにファイルをアップロードするために POST Rest サービスを実装しました。私が今抱えている問題は、アップロードされたファイルをそのタイプで制限したいということです。たとえば、.pdf ファイルのアップロードのみを許可したいとします。

私がやろうとしたことは

            Task<Stream> task = this.Request.Content.ReadAsStreamAsync();
            task.Wait();
            FileStream requestStream = (FileStream)task.Result;

残念ながら、Stream を FileStream にキャストし、requestStream.Name を介して型にアクセスすることはできません。

ファイルタイプを取得する簡単な方法はありますか (ストリームをディスクに書き込んでからタイプを確認する以外)。

4

1 に答える 1

9

ファイルを Web API にアップロードし、ファイル データにアクセスしたい場合 ( Content-Disposition)、ファイルを MIME マルチパートとしてアップロードする必要があります ( multipart/form-data)。

ここでは、HTML フォーム、Javascript、および .NET からアップロードする方法の例をいくつか示しました。

この例では、pdf/doc ファイルのみをチェックします。

public async Task<HttpResponseMessage> Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable,
                                                                   "This request is not properly formatted - not multipart."));
        }

        var provider = new RestrictiveMultipartMemoryStreamProvider();

        //READ CONTENTS OF REQUEST TO MEMORY WITHOUT FLUSHING TO DISK
        await Request.Content.ReadAsMultipartAsync(provider);

        foreach (HttpContent ctnt in provider.Contents)
        {
            //now read individual part into STREAM
            var stream = await ctnt.ReadAsStreamAsync();

            if (stream.Length != 0)
            {
                using (var ms = new MemoryStream())
                {
                    //do something with the file memorystream
                }
            }
        }
        return Request.CreateResponse(HttpStatusCode.OK);
    }
}

public class RestrictiveMultipartMemoryStreamProvider : MultipartMemoryStreamProvider
{
    public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
    {
        var extensions = new[] {"pdf", "doc"};
        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;

    }
}
于 2013-02-18T15:18:45.400 に答える