type the supported resource not net multipartformdatastreamprovider form for data asp and asp.net-web-api multipartform-data

asp.net web api - the - API web: cómo acceder a los valores de formulario multiparte al usar MultipartMemoryStreamProvider?



upload file web api 2 c# (1)

Actualizado el 28/04/2015

Puede crear un proveedor personalizado basado en MultipartFormDataRemoteStreamProvider .
Ejemplo:

public class CustomMultipartFormDataProvider : MultipartFormDataRemoteStreamProvider { public override RemoteStreamInfo GetRemoteStream(HttpContent parent, HttpContentHeaders headers) { return new RemoteStreamInfo( remoteStream: new MemoryStream(), location: string.Empty, fileName: string.Empty); } }

Actualizado

Custom In-Memory MultiaprtFormDataStreamProvider:

public class InMemoryMultipartFormDataStreamProvider : MultipartStreamProvider { private NameValueCollection _formData = new NameValueCollection(); private List<HttpContent> _fileContents = new List<HttpContent>(); // Set of indexes of which HttpContents we designate as form data private Collection<bool> _isFormData = new Collection<bool>(); /// <summary> /// Gets a <see cref="NameValueCollection"/> of form data passed as part of the multipart form data. /// </summary> public NameValueCollection FormData { get { return _formData; } } /// <summary> /// Gets list of <see cref="HttpContent"/>s which contain uploaded files as in-memory representation. /// </summary> public List<HttpContent> Files { get { return _fileContents; } } public override Stream GetStream(HttpContent parent, HttpContentHeaders headers) { // For form data, Content-Disposition header is a requirement ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition; if (contentDisposition != null) { // We will post process this as form data _isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName)); return new MemoryStream(); } // If no Content-Disposition header was present. throw new InvalidOperationException(string.Format("Did not find required ''{0}'' header field in MIME multipart body part..", "Content-Disposition")); } /// <summary> /// Read the non-file contents as form data. /// </summary> /// <returns></returns> public override async Task ExecutePostProcessingAsync() { // Find instances of non-file HttpContents and read them asynchronously // to get the string content and then add that as form data for (int index = 0; index < Contents.Count; index++) { if (_isFormData[index]) { HttpContent formContent = Contents[index]; // Extract name from Content-Disposition header. We know from earlier that the header is present. ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition; string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty; // Read the contents as string data and add to form data string formFieldValue = await formContent.ReadAsStringAsync(); FormData.Add(formFieldName, formFieldValue); } else { _fileContents.Add(Contents[index]); } } } /// <summary> /// Remove bounding quotes on a token if present /// </summary> /// <param name="token">Token to unquote.</param> /// <returns>Unquoted token.</returns> private static string UnquoteToken(string token) { if (String.IsNullOrWhiteSpace(token)) { return token; } if (token.StartsWith("/"", StringComparison.Ordinal) && token.EndsWith("/"", StringComparison.Ordinal) && token.Length > 1) { return token.Substring(1, token.Length - 2); } return token; } }

Uso :

public async Task Post() { if (!Request.Content.IsMimeMultipartContent("form-data")) { throw new HttpResponseException(HttpStatusCode.BadRequest); } var provider = await Request.Content.ReadAsMultipartAsync<InMemoryMultipartFormDataStreamProvider>(new InMemoryMultipartFormDataStreamProvider()); //access form data NameValueCollection formData = provider.FormData; //access files IList<HttpContent> files = provider.Files; //Example: reading a file''s stream like below HttpContent file1 = files[0]; Stream file1Stream = await file1.ReadAsStreamAsync(); }

Solía ​​usar MultipartFormDataStreamProvider para procesar solicitudes de varias partes. Como quiero que el archivo cargado se almacene en la memoria, en lugar de un archivo de disco, he cambiado mi código para usar MultipartMemoryStreamProvider. Parece que la carga del archivo funciona bien, pero ya no puedo acceder a otros valores de formulario que estaban disponibles a través de provider.FormData en MultipartFormDataStreamProvider. ¿Podría alguien mostrarme cómo hacer esto?

La solicitud sin procesar capturada por 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--

Mi código de controlador:

string payload = null; NameValueCollection nvc = null; string fname = null; StringBuilder sb = new StringBuilder(); sb.AppendLine(); foreach (StreamContent item in provider.Contents) { fname = item.Headers.ContentDisposition.FileName; if (!String.IsNullOrWhiteSpace(fname)) { payload = item.ReadAsStringAsync().Result; } else { nvc = item.ReadAsFormDataAsync().Result; } }