C# 如何在webapi上载中获取多部分文件的流?

C# 如何在webapi上载中获取多部分文件的流?,c#,azure,filestream,multipartform-data,asp.net-web-api2,C#,Azure,Filestream,Multipartform Data,Asp.net Web Api2,我需要使用Stream(Azure Blobstorage)上传一个文件,但无法找到如何从对象本身获取流。请参阅下面的代码 我是WebAPI新手,并使用了一些示例。我正在获取文件和文件数据,但它的类型不适合我上传它的方法。因此,我需要将其获取或转换为正常流,目前这似乎有点困难:) 我知道我需要以某种方式使用ReadAsStreamAsync().Result,但它在foreach循环中崩溃,因为我得到了两个provider.Contents(第一个似乎正确,第二个不正确) [System.Web

我需要使用Stream(Azure Blobstorage)上传一个文件,但无法找到如何从对象本身获取流。请参阅下面的代码

我是WebAPI新手,并使用了一些示例。我正在获取文件和文件数据,但它的类型不适合我上传它的方法。因此,我需要将其获取或转换为正常流,目前这似乎有点困难:)

我知道我需要以某种方式使用
ReadAsStreamAsync().Result
,但它在foreach循环中崩溃,因为我得到了两个provider.Contents(第一个似乎正确,第二个不正确)

[System.Web.Http.HttpPost]
公共异步任务上载()
{
如果(!Request.Content.IsMimeMultipartContent())
{
this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
var provider=GetMultipartProvider();
var result=wait Request.Content.ReadAsMultipartAsync(提供程序);
//上传时,文件的通用名称为“BodyPart_26d6abe1-3ae1-416a-9429-b35f15e6e5d5”
//因此,这就是获取原始文件名的方法
var originalFileName=GetDeserializedFileName(result.FileData.First());
//uploadedFileInfo对象会给你一些额外的东西,比如文件长度,
//创建时间、目录名、一些文件系统方法等。。
var uploadedFileInfo=newfileinfo(result.FileData.First().LocalFileName);
//如果不需要,请删除此行以及GetFormData方法
//随上载请求发送任何表单数据
var fileUploadObj=GetFormData(结果);
Stream filestream=null;
使用(Stream=newmemoryStream())
{
foreach(provider.Contents中的HttpContent内容)
{
BinaryFormatter bFormatter=新的BinaryFormatter();
序列化(stream,content.ReadAsStreamAsync().Result);
流位置=0;
filestream=流;
}
}
var storage=new StorageServices();
storage.UploadBlob(文件流,原始文件名);**强文本**
私有MultipartFormDataStreamProvider GetMultipartProvider()
{
var uploadFolder=“~/App\u Data/Tmp/FileUploads”;//您可以将其放入web.config
var root=HttpContext.Current.Server.MapPath(上传文件夹);
CreateDirectory(根目录);
返回新的MultipartFormDataStreamProvider(根);
}

这与我几个月前遇到的困境相同(在
MultipartStreamProvider
接管并自动神奇地将流保存到文件之前捕获上载流)。建议继承该类并重写方法…但在我的情况下,这不起作用。((我希望将
MultipartFileStreamProvider
MultipartFormDataStreamProvider
的功能合并到一个MultipartStreamProvider中,而不使用自动保存部分)


这可能会有所帮助;,来自同一位开发人员。

Hi只是想发布我的答案,这样,如果有人遇到同样的问题,他们可以在这里找到解决方案

这里

我使用MultipartMemoryStreamProvider,并从内容的标题中获取了所有详细信息,如文件名和文件类型。
希望这对某人有所帮助。

1.
GetMultipartProvider()
返回什么?2.我相信您可以从提供程序获得自动神奇保存的文件的文件路径,并使用常用的
System.IO.file
System.IO.FileInfo
类检索流。方法如下:)private MultipartFormDataStreamProvider GetMultipartProvider(){var uploadFolder=“~/App\u Data/Tmp/FileUploads”;//您可以将其放到web.config var root=HttpContext.Current.Server.MapPath(uploadFolder);Directory.CreateDirectory(root);返回新的MultipartFormDataStreamProvider(root);}我可以从这里获取文件吗?基本上我不需要将其存储到磁盘。我只需要上传到azure blob存储的流:)有什么想法吗?这与我几个月前遇到的困境完全相同(在
MultipartStreamProvider
接管并自动将流保存到文件之前捕获上载流)。建议继承该类并重写方法……但这在我的情况下不起作用。:(这可能有帮助;这里是。这也是同一个开发人员提出的。关于这一点,只有一个问题:)如何/从何处获取和引用multipartstreamprovider?在system.net.http中找不到它。我有.net 4.5:)目前,它位于NuGet软件包中的
system.net.Formatting.dll中。以下是(它几乎一年没有更改过)。感谢您的支持;)是的!!…它正在工作:)现在唯一恼人的事情是我无法获取剩余的formdata:(以前使用过-->私有对象GetFormData(MultipartFormDataStreamProviderResult){if(result.formdata.HasKeys()){var unescapedFormData=Uri.UnescapeDataString(result.FormData.GetValues(0).FirstOrDefault()??String.Empty);if(!String.IsNullOrEmpty(unescapedFormData))返回JsonConvert.DeserializeObject(unescapedFormData);}返回null;}猜这也是您的问题吗?;)
 [System.Web.Http.HttpPost]
    public async Task<HttpResponseMessage> Upload()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
        }

        var provider = GetMultipartProvider();
        var result = await Request.Content.ReadAsMultipartAsync(provider);

        // On upload, files are given a generic name like "BodyPart_26d6abe1-3ae1-416a-9429-b35f15e6e5d5"
        // so this is how you can get the original file name
        var originalFileName = GetDeserializedFileName(result.FileData.First());

        // uploadedFileInfo object will give you some additional stuff like file length,
        // creation time, directory name, a few filesystem methods etc..
        var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);



        // Remove this line as well as GetFormData method if you're not
        // sending any form data with your upload request
        var fileUploadObj = GetFormData<UploadDataModel>(result);

        Stream filestream = null;

        using (Stream stream = new MemoryStream())
        {
            foreach (HttpContent content in provider.Contents)
            {
                BinaryFormatter bFormatter = new BinaryFormatter();
                bFormatter.Serialize(stream, content.ReadAsStreamAsync().Result);
                stream.Position = 0;
                filestream = stream;
            }
        }

        var storage = new StorageServices();
        storage.UploadBlob(filestream, originalFileName);**strong text**



private MultipartFormDataStreamProvider GetMultipartProvider()
    {
        var uploadFolder = "~/App_Data/Tmp/FileUploads"; // you could put this to web.config
        var root = HttpContext.Current.Server.MapPath(uploadFolder);
        Directory.CreateDirectory(root);
        return new MultipartFormDataStreamProvider(root);
    }
 MultipartMemoryStreamProvider stream = await this.Request.Content.ReadAsMultipartAsync();
            foreach (var st in stream.Contents)
            {
                var fileBytes = await st.ReadAsByteArrayAsync();
                string base64 = Convert.ToBase64String(fileBytes);
                var contentHeader = st.Headers;
                string filename = contentHeader.ContentDisposition.FileName.Replace("\"", "");
                string filetype = contentHeader.ContentType.MediaType;
            }