ServiceStack request POST body as query string - c#

I am trying to implement an IPN handler in C# and I am using ServiceStack as my backend framework. I am facing the following issue however;
I am trying to find a way to take the POST body of a request as a querystring but I fail to do so. I am using IRequest.GetRawBody(); but the POST data are returned in a formatted way to make it readable.
Is there any way to easily take the POST body as a querystring? I want something similar to PHP's $_POST so I can ecrypt the data with HMAC SHA256 but I can find a way to do it without writing a helper class with hardcoded details about the POST request body. I've tried searching online and ServiceStack's documentation but I did not find anything useful.
Any help will be very appreciated, thanks in advance!

The QueryString is on the URL not the Request Body. If you just want access to the raw Request body that's posted you can have your Request DTO implement IRequiresRequestStream which tells ServiceStack to skip deserializing the body so you can deserialize it yourself, e.g:
public class MyRequest : IRequiresRequestStream
{
public Stream RequestStream { get; set; }
}
public class MyServices : Service
{
public object Any(MyRequest request)
{
var bytes = request.RequestStream.ReadFully();
var text = bytes.FromUtf8Bytes();
...
}
}

Related

How to create a web Api have http post function which can take any dynamic json content from body and able to parse it into string

I have an third party event that post data to my hosted API but the problem is I don't know the Json structure which event posting to my API from Body. I need to read the json content posted by Event to my API.
I have tried to create post method as dynamic or string type the event able to call the service but data is not get typecast, it shows null always.
[HttpPost]
RecievedPayload([FromBody]dynamic json)
{
}
[HttpPost]
RecievedPayload([FromBody]string json)
{
}
RecievedPayload Api method is getting invoked by Third party Event but the json content is null. I need to know the Json structure so that I can make a custom class to hold the content.
There isn't a simple way to just get the whole body as a parameter.
This blog post is worth a full read: https://weblog.west-wind.com/posts/2013/dec/13/accepting-raw-request-body-content-with-aspnet-web-api
However to accomplish your goal, this is a slightly modified version of a code sample provided in the blog post, which should work for your needs:
[HttpPost]
public async Task<string> RecievedPayload()
{
string result = await Request.Content.ReadAsStringAsync();
return result;
}
Also worth reading: https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

ASP.NET Web Api - the framework is not converting JSON to object when using Chunked Transfer Encoding

I have an http client in Android sending HTTP PUT requests to a REST api implemented with C# and ASP.NET WebApi framework.
The framework should be able to magically convert (deserialize) the JSON into a model class (plain object) as long as the JSON fields match the properties in the C# class.
The problem comes when the http requests come with Chunked Transfer Encoding that makes the Content-Length = 0 (as per http://en.wikipedia.org/wiki/Chunked_transfer_encoding) and the framework is not able to map the JSON that's within the Http request message so the parameter is null.
See this simple example:
[HttpPut]
public HttpStatusCode SendData(int id, int count, [FromBody]MyData records, HttpRequestMessage requestMessage)
{
var content = requestMessage.Content;
string jsonContent = content.ReadAsStringAsync().Result; //this gets proper JSON
return HttpStatusCode.OK;
}
The problem is that records is null when the client sends the http request chunked.
As I understand, the Chunked Transfer encoding is simply a transfer property that the http client or server should not have to worry about at the application layer (transport layer's business). But it seems the framework doesn't manage it as I'd like.
I could manually retrieve the JSON from the HttpRequestMessage and de-serialize it into a MyData object, but I wouldn't be able to take advantage of the ASP.NET framework's magic. And you know the rule: the more code you add the more bugs you are likely to introduce.
Is there any way to handle Http Put requests with JSON that come as chunked transfer encoded in ASP.NET Web Api 2?
EDIT: This is the model class for this example that the framework should instantiate when de-serializing the JSON
public class MyData
{
public string NamePerson {get; set;}
public int Age {get; set;}
public string Color {get; set;}
}
I recently stumbled upon the the same issue, and managed to create a workaround for it. I took the original JsonMediaTypeFormatter class, subclassed it and updated the implementation of the ReadFromStreamAsync/ReadFromStream-method.
https://gist.github.com/cobysy/578302d0f4f5b895f459
Hope this helps.

Insert JSON from URL string

I have created a REST web service that should get a JSON string and convert it to an object in C#. I have created my classes and used the deserialization:
RootObject test = JsonConvert.DeserializeObject<RootObject>("id");
So far so good, I need to call my function :
public string JSONData(string id)
Is there a way to insert my JSON in the URL so I can trigger my function, or am I missing something fundamental?
http://localhost/RestSrv/Json/....
What should I put in the ... that will give value to my id string and call my JSONData function that will deserialize the JSON after? Should I use an online JSON convert to URL tool?
I can think of two ways to do this
Send JSON via HTTP POST with Content-Type: application/json header
Send HTTP Query String with the required data. For example
?object[type]=person&children_names[]=Mia&children_names[]=Anna
Would convert to JSON (https://www.convertonline.io/convert/query-string-to-json)
{"object":{"type":"person"},"children_names":["Mia","Anna"]}
Option 1 is better since URL string can be long and have a length limitation.

Posting data to asp.net Web API

I'm trying to figure out the new ASP.NET Web API.
So far I've been able to create this method signature and connect to it just fine and get a valid response...
[HttpPost]
public HttpResponseMessage CreateAccount()
I am able to send a request to this method with fiddler and have verified that it is receiving the request.
However, when I try to pass data is when I am running into a problem.
The first thing I tried was...
[HttpPost]
public HttpResponseMessage CreateAccount([FromBody]string email, [FromBody]string password)
And I type
email:xyz,password:abc
into the body of the request in fiddler. When I do this I get a 500 error stating
'Can't bind multiple parameters ('email' and 'password') to the request's content.'
I have also tried this as a method signature...
[HttpPost]
public HttpResponseMessage CreateAccount([FromBody]UserAccountRequestData data)
with the UserAccountRequestData being a simple POCO
public class UserAccountRequestData
{
public string Email { get; set; }
public string Password { get; set; }
}
And I put
{Email:xyz,Password:abc}
or
data:{Email:xyz,Password:abc}
into the body of the request. In both cases trying to populate the POCO I am able to reach the method while debugging, but the data object is always null.
I need to understand how to create API methods that accept both strongly typed POCOs and others that accept multiple primitive types like strings and ints.
Thanks
You need to set the Content-Type header to application/json and then provide valid JSON.
{"Email":"xyz","Password":"abc"}

How Do I De-Serialize JSON From the Facebook Graph API?

So i'm trying to de-serialize the JSON returned from the Graph API OAuth Token call.
The JSON looks like this:
"[{\"access_token\":\"bunchofjsondatablahblah",\"expires\":9999}]"
I'm trying to de-serialize it (using the DataContractJsonSerializer class) into this object:
[DataContract]
internal class FacebookOAuthToken
{
[DataMember]
internal string access_token;
[DataMember]
internal string expires;
}
Here's how im (trying) to do it:
FacebookOAuthToken token;
using (Stream responseStream = (response.GetReponseStream()))
{
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(FacebookOAuthToken));
token = (FacebookOAuthToken)json.ReadObject(responseStream);
}
This technique is based on this article from MSDN.
However, the properties of token are always null.
Whereas if i do responseStream.ReadToEnd(), it's all fine (returns the above JSON) - which means its not a problem with the actual HTTP request/response, i'm just not deserializing it properly.
What am i doing wrong?
Okay so it turns out i was using the wrong Graph API URL (so it seems).
This is the problem with the Facebook API Documentation, its all over the place and different threads (google, stack overflow) say different ways how to do things.
I changed to the URL https://graph.facebook.com/oauth/access_token?{0} instead of https://graph.facebook.com/oauth/exchange_sessions?{0} and it now returns a basic string (non-JSON).
So it doesnt need to be serialized at all.
Still, some people might have the same problem as me above, in that case im not sure how to solve.
I'm now using the method defined here.
If I interpret the JSON string correctly it represents a collection of FacebookOAuthToken items with one single instance in it and not just a single token.
Maybe that is why your deserialization did not work.

Categories