【问题标题】:ASP.NET WebApi file upload using guid and file extension使用 guid 和文件扩展名的 ASP.NET WebApi 文件上传
【发布时间】:2013-06-04 04:33:02
【问题描述】:

我目前能够保存上传到 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 可能是候选人,但似乎没有人满。

【问题讨论】:

  • 这是一个类似的问题,有一个答案 [stackoverflow.com/questions/14937926/… [1]: stackoverflow.com/questions/14937926/…
  • 您能分享一下您的请求标头是什么样的吗?您是否在请求中填充了 ContentDisposition 标头?
  • 设置此类标头是客户端的责任。你的客户是什么样的?
  • @Kiran:不,它没有被填充。此外,所有示例似乎都使用流提供程序来加载流。我想在不使用提供程序的情况下阅读它并使用 guid 和扩展名保存文件。不使用流提供程序的原因是它似乎不允许我返回为文件创建的 guid 调用函数。

标签: file-upload asp.net-web-api


【解决方案1】:

感谢上面的 cmets 为我指明了正确的方向。

为了阐明最终解决方案,我使用了 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;       
    }
}

【讨论】:

  • var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty); 处引发空引用异常。通过在执行 Replace() 之前检查 filename 是否不为空来修复。
  • 你为什么要覆盖 GetStream 方法?
猜你喜欢
  • 2014-04-06
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 2011-05-13
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多