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

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.

Related

Is it possible to set a custom request method with RestSharp?

I'm working on a C# console application which calls external REST APIs with RestSharp.
The issue now is that I have to access an API that only allows a custom request method like FOOBAR instead of the traditional GET or POST.
using RestSharp;
var request = new RestRequest();
request.Method = Method.POST;
Unfortunately, I haven't seen anything pertaining to custom request methods in RestSharp's docs or GitHub issues section.
Keep in mind that I only have a basic knowledge on this, so my trials might be considered silly.
I've tried assigning a string to it but it only accepts an enum.
request.Method = "FOOBAR"; // Does not accept strings
I've also tried converting a string to enum using code from this answer, but this defaults to a GET. It might be like that due to my converted string not being in their enum Method.
Enum.TryParse("FOOBAR", out Method customRequestMethod);
request.Method = customRequestMethod; // Defaults to GET
If this is not possible with RestSharp, is this feature doable with HttpClient or Flurl?

ServiceStack request POST body as query string

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

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.

FormatExcpetion from Azure Webjobs Host

Understand this is pre-release :)
When trying to use QueueInput in Azure WebJobs and sticking the hex string of a hash in the message.
public System.Guid GetOwner(CloudQueueMessage msg)
Looking at ilspy seems like it is trying to parse out $AzureJobsParentId and the JSON parser is throwing the exception I can get around it by encoding my hash in a JSON snippet but I'd prefer not to. Is this a known bug?
[QueueInput] will normally use JSON.Net to deserialize the queue message payload to the parameter type. So if the queue message is not JSON, you'll get a exception (which should then be wrapped in something more friendly).
You can also work around it by using a string parameter with [QueueInput], like:
public static void Function([QueueInput] string testqueue)
{
}
For string parameter, the SDK will give you the QueueMessage.AsString directly, without any JSON serialization.
FYI, $AzureJobsParentId is a special field placed on json payloads that identifies which function instance enqueued a message. This gets used when you enqueue a message with [QueueOutput]. You can then view that relationship in the SDK dashboard (http://blogs.msdn.com/b/jmstall/archive/2014/01/27/getting-a-dashboard-for-local-development-with-the-webjobs-sdk.aspx)

Retrieve Inner XML in WCF from XMLHTTP POST Request

Hi and good day everyone,
I am able to send XML HTTP POST Request to WCF after solving it through this topic: Handle POST request from XML HTTP in WCF
But right now, I am still trying to find right way to retrieve inner XML from the request. I send the request in XML form :
<?xml version=""1.0"" encoding=""UTF-8"" standalone= ""yes""?><AFISQuery transid=""3356434""><Request CIFNO =""1234567890123456789"" IC= ""770707-07-7777"">TEST</Request></AFISQuery>
In the AFISQuery class, I set it as:
[DataContract(Namespace = "")]
public class AFISQuery
{
public AFISQuery(string transid)
{
this.transid = transid;
}
[DataMember]
public string Request { get; set; }
[DataMember]
public string transid { get; set; }
}
As the result, I am able to get Request information ("TEST"), but could not get transid information. I tried to look around the forums but failed to find similar problems.
My question is, would it be possible to retrieve the information from the inner XML of the request? For this instance, they are CIFNo, transid and ICNo.
Thanks in advance :)
The reason you're able to retrieve Request is that Request is an XML element. XML elements map directly to DataMembers, and as a result, Request is deserialized properly to the Request DataMember on the AFISQuery data contract type.
The problem with 'transid' is that it's an attribute. Attributes are not supported with DataContractSerializer, and they cannot in any way be supported. You need to change your request XML so that it has transid as an element, just like Request is an element.
Note also that even though Request is set to a value for you right now, the attributes on the "Request" element in the XML you have are totally ignored. You may or may not be OK with this.
If you care about attributes, or if you do want to support serializable members as attributes, you may need to switch to XmlSerializer from DataContractSerializer. It's easy to do this, just decorate the services or operations you care about -- that you want to switch over to XmlSerializer -- with [XmlSerializerFormat.]

Categories