¿Cómo puedo leer el contenido de la solicitud PUT en MVC webApi acción del controlador.

[HttpPut]
public HttpResponseMessage Put(int accountId, Contact contact)
{
    var httpContent = Request.Content;
    var asyncContent = httpContent.ReadAsStringAsync().Result;
...

Puedo conseguir cadena vacía aquí 🙁

Lo que necesito hacer es: averiguar «qué propiedades» fueron modificados/enviado en la petición inicial (lo que significa que si el Contact objeto tiene 10 propiedades, y quiero actualizar a sólo 2 de ellos, puedo enviar y objeto con dos propiedades, algo como esto:

{

    "FirstName": null,
    "LastName": null,
    "id": 21
}

El resultado final esperado es

List<string> modified_properties = {"FirstName", "LastName"}
InformationsquelleAutor Marty | 2012-09-19

4 Comentarios

  1. 126

    Por diseño, el contenido del cuerpo en ASP.NET la API de Web es tratada como secuencia de sólo avance que puede ser leído sólo una vez.

    La primera lectura en su caso, es que se realiza cuando la API de Web es vinculante para el modelo, después de que el Request.Content no va a devolver nada.

    Puede quitar el contact de sus parámetros de acción, obtener el contenido y deserializar manualmente en un objeto (por ejemplo con Json.NET):

    [HttpPut]
    public HttpResponseMessage Put(int accountId)
    {
        HttpContent requestContent = Request.Content;
        string jsonContent = requestContent.ReadAsStringAsync().Result;
        CONTACT contact = JsonConvert.DeserializeObject<CONTACT>(jsonContent);
        ...
    }

    Que debe hacer el truco (suponiendo que accountId es parámetro de URL, por lo que no será tratada como leer el contenido).

    • Thanx. Y sí, el id de la cuenta es un parámetro url.
    • Me pregunto si usted podría crear un MessageHandler que se llama LoadIntoBuffer() en el contenido de solicitud antes de que el Modelo de cuaderno de una patada en.
    • No estoy seguro de si ASP.NET Web API todavía enlazar el modelo necesita ser probado.
    • Será esta la causa de los Interbloqueos?
    • Como es, no puede. Usted debe cambiar la acción de la firma para async y uso esperan.
    • ¿por qué sólo puede ser leída de una sola vez? Sólo me preguntaba si había alguna razón para esto cuando se diseñó.

  2. 18

    Usted puede mantener su CONTACTO parámetro con el siguiente enfoque:

    using (var stream = new MemoryStream())
    {
        var context = (HttpContextBase)Request.Properties["MS_HttpContext"];
        context.Request.InputStream.Seek(0, SeekOrigin.Begin);
        context.Request.InputStream.CopyTo(stream);
        string requestBody = Encoding.UTF8.GetString(stream.ToArray());
    }

    Volvió para mí la representación json de mi objeto de parámetro, de modo que se podía utilizar para el manejo de excepciones y registro.

    Encontrado aceptado como respuesta aquí

  3. 4

    Aunque esta solución puede parecer obvio, yo sólo quería publicar aquí por lo que el tipo de al lado, google es más rápido.

    Si quieres tener el modelo como parámetro en el método, usted puede crear un DelegatingHandler para amortiguar el contenido.

    internal sealed class BufferizingHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            await request.Content.LoadIntoBufferAsync();
            var result = await base.SendAsync(request, cancellationToken);
            return result;
        }
    }

    Y agregar a los controladores de mensaje global:

    configuration.MessageHandlers.Add(new BufferizingHandler());

    Esta solución se basa en la respuesta por Darrel Miller.

    De esta manera todas las solicitudes se podrán almacenar en búfer.

    • Creo que podría tanque de mi servidor perf… pero que podría ser útil.
  4. -6

    La manera más fácil para leer el contenido de cualquier solicitud que generalmente es el uso de un proxy http, como fiddler

    Que tiene la gran ventaja de mostrar todos tráfico local (además de la completa de las solicitudes de los encabezados, etc) y un montón de otras peticiones que la lectura de la Solicitud de contenido dentro de una determinada acción en un controlador en particular no mostrar – por ejemplo, 401 /404 etc.

    También puede utilizar el violinista compositor para crear solicitudes de prueba desde cero o modificando las solicitudes anteriores.

    Si por alguna razón no se puede utilizar un proxy o debe ver la solicitud desde dentro de la aplicación web, a continuación, esta respuesta parece sensato

Dejar respuesta

Please enter your comment!
Please enter your name here