Asp.net web api Web API:使用MultipartMemoryStreamProvider时如何访问多部分表单值?

Asp.net web api Web API:使用MultipartMemoryStreamProvider时如何访问多部分表单值?,asp.net-web-api,multipartform-data,Asp.net Web Api,Multipartform Data,我曾经使用MultipartFormDataStreamProvider来处理多部分请求 由于我希望上传的文件存储在内存中,而不是磁盘文件,因此我已将代码更改为使用MultipartMemoryStreamProvider。文件加载似乎工作正常,但我无法再访问 通过MultipartFormDataStreamProvider下的提供程序.FormData提供的其他表单值。有人能告诉我怎么做吗 Fiddler捕获的原始请求: POST http://myserver.com/QCCSvcHost

我曾经使用
MultipartFormDataStreamProvider
来处理多部分请求

由于我希望上传的文件存储在内存中,而不是磁盘文件,因此我已将代码更改为使用
MultipartMemoryStreamProvider
。文件加载似乎工作正常,但我无法再访问 通过
MultipartFormDataStreamProvider
下的
提供程序.FormData
提供的其他表单值。有人能告诉我怎么做吗

Fiddler捕获的原始请求:

POST http://myserver.com/QCCSvcHost/MIME/RealtimeTrans/ HTTP/1.1
Content-Type: multipart/form-data; boundary="XbCY"
Host: na-w-lxu3
Content-Length: 1470
Expect: 100-continue
Connection: Keep-Alive

--XbCY
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=PayloadType

X12_270_Request_005010X279A1
--XbCY
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=ProcessingMode

RealTime
--XbCY
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=PayloadID

e51d4fae-7dec-11d0-a765-00a0c91e6fa6
--XbCY
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=TimeStamp

2007-08-30T10:20:34Z
--XbCY
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=SenderID

HospitalA
--XbCY
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=ReceiverID

PayerB
--XbCY
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=CORERuleVersion

2.2.0
--XbCY
Content-Disposition: form-data; name=Payload; filename=276_5010.edi

ISA*00*~SE*16*0001~GE*1*1~IEA*1*191543498~
--XbCY--
我的控制器代码:

字符串有效负载=null;
NameValueCollection nvc=null;
字符串fname=null;
StringBuilder sb=新的StringBuilder();
(某人);
foreach(provider.Contents中的StreamContent项)
{
fname=item.Headers.ContentDisposition.FileName;
如果(!String.IsNullOrWhiteSpace(fname))
{
有效负载=item.ReadAsStringAsync().Result;
}
其他的
{
nvc=item.ReadAsFormDataAsync().Result;
}
}

于2015年4月28日更新

您可以基于
MultipartFormDataRemoteStreamProvider
创建自定义提供程序
例如:

公共类CustomMultipartFormDataProvider:MultipartFormDataRemoteStreamProvider { 公共覆盖RemoteStreamInfo GetRemoteStream(HttpContent父级,HttpContentHeaders标头) { 返回新的RemoteStreamInfo( remoteStream:新的MemoryStream(), 位置:string.Empty, 文件名:string.Empty); } }
已更新

自定义内存中多APRTFORMDataStreamProvider:

MemoryMultipartFormDataStreamProvider中的公共类:MultipartStreamProvider { 私有NameValueCollection_formData=新NameValueCollection(); 私有列表_fileContents=新列表(); //HttpContents指定为表单数据的索引集 私有集合_isFormData=新集合(); /// ///获取作为多部分表单数据的一部分传递的表单数据。 /// public NameValueCollection表单数据 { 获取{return\u formData;} } /// ///获取以内存表示形式包含上载文件的列表。 /// 公共列表文件 { 获取{return\u fileContents;} } 公共重写流GetStream(HttpContent父级、HttpContentHeaders头) { //对于表单数据,需要内容处置标头 ContentDispositionHeaderValue contentDisposition=headers.contentDisposition; if(contentDisposition!=null) { //我们将把它作为表单数据进行后期处理 _Add(String.IsNullOrEmpty(contentDisposition.FileName)); 返回新的MemoryStream(); } //如果不存在内容处置标头。 抛出新的InvalidOperationException(string.Format(“在MIME多部分正文部分中未找到必需的“{0}”头字段…,“内容处置”); } /// ///将非文件内容作为表单数据读取。 /// /// 公共覆盖异步任务ExecutePostProcessingAsync() { //查找非文件HttpContents的实例并异步读取它们 //获取字符串内容,然后将其作为表单数据添加 for(int index=0;index1) { 返回token.Substring(1,token.Length-2); } 返回令牌; } } 用法

public async Task Post()
{
if(!Request.Content.IsMimeMultipartContent(“表单数据”))
{
抛出新的HttpResponseException(HttpStatusCode.BadRequest);
}
var provider=wait Request.Content.ReadAsMultipartAsync(新的InMemoryMultipartFormDataStreamProvider());
//访问表单数据
NameValueCollection formData=provider.formData;
//访问文件
IList files=provider.files;
//示例:读取文件流,如下所示
HttpContent file1=文件[0];
Stream file1Stream=wait file1.ReadAsStreamAsync();
}

基于Kiran的优秀答案,我从2015年4月的更新中收集了完整答案。看起来WebAPI中至少有一件事发生了变化,这让我开始感到困惑。provider.Files不再存在,它是.Content。因此,为了在不首先将文件存储在磁盘上的情况下读取发布的文件,您至少需要执行以下操作:

步骤1:创建提供者类

为此类在项目中的某个位置添加文件:

public class InMemoryMultipartFormDataProvider : MultipartFormDataRemoteStreamProvider
{
   public override RemoteStreamInfo GetRemoteStream(HttpContent parent, HttpContentHeaders headers)
   {
      return new RemoteStreamInfo(
                remoteStream: new MemoryStream(),
                location: string.Empty,
                fileName: string.Empty);
   }
}
我相信这会将每个文件转换为内存流,而不是将其存储在磁盘上

步骤2:添加控制器操作解析内容并创建str
[HttpPost]
public async Task<IHttpActionResult> Upload()
{
   // This endpoint only supports multipart form data
   if (!Request.Content.IsMimeMultipartContent("form-data"))
   {
      return StatusCode(HttpStatusCode.UnsupportedMediaType);
   }

   // read the content in a memory stream per file uploaded
   var provider = await Request.Content.ReadAsMultipartAsync<InMemoryMultipartFormDataProvider>(new InMemoryMultipartFormDataProvider());

   // iterate over each file uploaded and do something with the results
   foreach (var fileContents in provider.Contents) {
      processFileAsMemoryStream(await fileContents.ReadAsStreamAsync());
   }
}