visual studio paso net example ejemplo create crear asp c# asp.net asp.net-web-api

studio - web api c# ejemplo



Cómo conseguir contenido ya leído. (3)

No incluya el parámetro del cuerpo en la firma y eso le permitirá almacenar el contenido y leerlo tantas veces como lo desee.

[PUT("user/{UserId}")] public HttpResponseMessage Put(string userId) { Request.Content.LoadIntoBufferAsync().Wait(); var paymentRequest = Request.Content.ReadAsAsync<PaymentRequest>().Result; var requestBody = Request.Content.ReadAsStringAsync().Result; // Calling business logic and so forth here // Return proper HttpResponseMessage here }

Tengo una clase que hereda de ApiController. Tiene un método Put como este:

[PUT("user/{UserId}")] public HttpResponseMessage Put(string userId, PaymentRequest paymentRequest) { // Calling business logic and so forth here // Return proper HttpResponseMessage here }

El método funciona bien como está arriba. Ahora necesito validar la firma de la llamada al método, pero aquí me encuentro con un problema. La firma es esencialmente una combinación de método + url + cuerpo. El método que puedo obtener llamando a Request.Method y la url que puedo obtener llamando a Request.RequestUri.ToString (), pero no puedo controlar el cuerpo como estaba antes de que se deserializara automáticamente en un objeto PaymentRequest por el asp.net MVC4 framework.

Mi primer intento: como lo he entendido Request.Content.ReadAsStringAsync (). El resultado no devuelve nada. Esto se debe a que el contenido solo se puede leer una vez.

Mi segundo intento: intenté serializarlo de nuevo a una cadena JSON.

var serializer = new JavaScriptSerializer(); var paymentRequestAsJson = serializer.Serialize(paymentRequest);

El problema con esto es que el formato resulta ligeramente diferente a la parte del cuerpo de la firma. Tiene los mismos datos, pero algunos espacios más.

No puedo cambiar lo que hace el llamador de mi método Put, ya que este es un componente de terceros. ¿Qué tengo que hacer?


Una respuesta muy retrasada, pero recientemente he tenido el mismo desafío que superar.

Lo he abordado de forma un poco diferente sin tener que obtener los datos de httpContext (puede ser bastante costoso para la aplicación web de transacciones de alto volumen).

Creé una interfaz simple e hice que cada Controlador la implementara:

public interface IBaseControllerData { object Entity { get; set; } }

Luego, he establecido la propiedad Entidad del Controlador en la carga Json para cada publicación y acción. Finalmente, recuperé los datos de la Entidad dentro del método sobrescrito ActionFilterAttribute.OnActionExecuted y lo serialicé a Json antes de inyectarlo en MongoDB:

object entity = ((IBaseControllerData)actionExecutedContext.ActionContext.ControllerContext.Controller).Entity; requestBody = Newtonsoft.Json.JsonConvert.SerializeObject(entity);

Espero que ayude !

Aclamaciones


Usted podría leer de la solicitud subyacente:

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()); }