Solía usar MultipartFormDataStreamProvider para procesar los pedidos.

Ya que quiero que el archivo subido para ser almacenados en la memoria, en lugar de un archivo de disco, he cambiado mi código para utilizar MultipartMemoryStreamProvider. La carga del archivo parece estar funcionando bien, pero yo no soy capaz de acceder a
otra forma los valores que estaban disponibles a través de provider.FormData bajo MultipartFormDataStreamProvider. Es posible que alguien me muestre cómo hacer esto?

Sin procesar la solicitud en la captura de 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;
    }
}
InformationsquelleAutor user2434400 | 2013-06-12

1 Comentario

  1. 117

    Actualizado 4/28/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

    Personalizado En la memoria 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();
    }
    • Gracias Kiran para la entrada. Cuando me tratan de lo que usted sugiere, no parece como la línea de NameValueCollection nvc = esperan de contenido.ReadAsFormDataAsync(); por alguna razón. Estoy recibiendo el error:.»ExceptionMessage:No MediaTypeFormatter está disponible para leer un objeto de tipo ‘FormDataCollection» de contenido con los medios de comunicación de tipo ‘multipart/form-data'». Alguna idea?
    • Es que este ‘contenido’ así como lo he mencionado anteriormente, que es el contenido de la matriz de contenido? pregunto esto porque parece que se intenta leer el contenido de la solicitud de todo, más que el contenido interior
    • He intentado tanto: nvc = Solicitud.Contenido.ReadAsFormDataAsync().Resultado; y nvc = proveedor.Contenido[0].ReadAsFormDataAsync().Resultado; Pero estoy recibiendo errores similares.
    • Hmm…¿podría explicar cómo su prima petición parece? y también el código que usted ha…
    • Kiran, yo no podía entender cómo agregar código y solicitar el comentario lo he editado mi origional post. Mi conjetura es que la solicitud es correcta, ya que trabajó con MultipartFormDataStreamProvider. Gracias de nuevo!
    • Gracias para más información. Parece que estaba equivocado acerca de ReadAsFormDataAsync() como se ve por mediatype application/x-www-form-urlencoded. Ahora he modificado mi código en el post. Déjame saber si esto funciona.
    • Gracias de nuevo! Voy a darle una oportunidad y dejar que ustedes saben. Realmente aprecio su ayuda!
    • Funciona de maravilla Kiran! Muchas gracias por su ayuda! Yo estoy un poco sorprendido de que en la Web de la API de no hacer esto más conveniente y nos ahorra la molestia de escribir código de análisis. Que tengan un gran día!
    • Me alegro de que ayudó!. Sí, estoy totalmente de acuerdo. Voy a llevar esto hasta el equipo. Gracias!. Por CIERTO, lo siento por las varias actualizaciones en el post anterior. He incluido un ejemplo completo.
    • Lástima que no tengo suficiente «repatation» punto de votar este anwser arriba. Recomiendo a alguien hacer esto. Muchas cosas de las que Kiran!
    • fue a través de un montón de tutoriales y sitios, y este post fue la única cosa que me levanto y de trabajo. buen trabajo y gracias 🙂
    • +1 Exactamente lo que yo necesitaba. Gracias hombre.
    • Grandes cosas. Gracias bro
    • Esta respuesta me ha ayudado mucho!!
    • Esa línea de código: devolver el token.Substring(1, token.Longitud – 2); no funciona. mi nombre de archivo tiene comillas alrededor del nombre de archivo y que, literalmente, no se elimina. Esto cambia la extensión del archivo .txt a .txt» que causa un problema para el usuario final abrir el archivo… «
    • Fantástico trabajo! Esto debe ser incluido en el .Net framework.

Dejar respuesta

Please enter your comment!
Please enter your name here