I have a class that inherits from ApiController. It has a Put-method like this:
[PUT("user/{UserId}")] public HttpResponseMessage Put(string userId, PaymentRequest paymentRequest) { // Calling business logic and so forth here // Return proper HttpResponseMessage here }
The method works fine as it is above. Now I need to validate the signature of the method call, but here I run into a problem. The signature is essentially a combination of method + url + body. The method I can get by calling Request.Method and the url I can get by calling Request.RequestUri.ToString(), but I can't get hold of the body as it was before it was automatically deserialized into a PaymentRequest object by the asp.net MVC4 framework.
My first try: As I have now understood Request.Content.ReadAsStringAsync().Result returns nothing. This is because the content can only be read once.
My second try: I tried to serialize it back to a JSON string.
var serializer = new JavaScriptSerializer(); var paymentRequestAsJson = serializer.Serialize(paymentRequest);
The problem with this is that the formatting turns out slightly different than the body part of the signature. It has the same data, but some more spaces.
I can't change what the caller of my Put-method does, as this is a third party component. What should I do?
After reading, you may find it almost impossible to retain the information acquired. It may be due to lack of adequate sleep and rest, distractions while reading, poor nutrition, failure to choose the right book, or memory issues such as decay or shallow processing.
You could read from the underlying request:
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()); }
Don't include the body parameter in the signature and that will allow you to buffer the content and read the content as many times as you like.
[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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With