Deserializing JsonArray - c#

I've written a code which calls an API which returns a Json Array which I have tired to deserialize using Json.net as below-
static async void MakeAnalysisRequest(string imageFilePath)
{
HttpClient client = new HttpClient();
// Request headers.
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
// Request parameters. A third optional parameter is "details".
string requestParameters = "returnFaceId=true";
// Assemble the URI for the REST API Call.
string uri = uriBase + "?" + requestParameters;
HttpResponseMessage response;
// Request body. Posts a locally stored JPEG image.
byte[] byteData = GetImageAsByteArray(imageFilePath);
using (ByteArrayContent content = new ByteArrayContent(byteData))
{
// This example uses content type "application/octet-stream".
// The other content types you can use are "application/json" and "multipart/form-data".
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// Execute the REST API call.
response = await client.PostAsync(uri, content);
// Get the JSON response.
string contentString = await response.Content.ReadAsStringAsync();
// Display the JSON response.
Console.WriteLine("\nResponse:\n");
List<Facejson> obj=JsonConvert.DeserializeObject<List<Facejson>>(contentString);
Console.WriteLine(obj[0].Face.faceId);
}
}
public class Facejson
{
[JsonProperty("face")]
public Face Face { get; set; }
}
public class Face
{
[JsonProperty("faceId")]
public string faceId { get; set; }
}
The Api response Json is in the format
[
{
"faceId": "f7eda569-4603-44b4-8add-cd73c6dec644",
"faceRectangle": {
"top": 131,
"left": 177,
"width": 162,
"height": 162
}
},
{
"faceId": "f7eda569-4603-44b4-8add-cd73c6dec644",
"faceRectangle": {
"top": 131,
"left": 177,
"width": 162,
"height": 162
}
}
]
When I compile my code, the following error shows up
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
in the line
Console.WriteLine(obj[0].Face.faceId);
I have declared the method "Face" but it shows that I have not. What am I doing wrong?
Edit- fixed Json and faulty code fixed as suggested.

You are deserializing a List<Face>, so to access one item on this list, you will have to use an index:
Console.WriteLine( obj[0].Face.faceId );
Or enumerate all results one-by-one:
foreach ( var face in obj )
{
Console.WriteLine( face.Face.faceId );
}
Update
You are deserializing a wrong type. Your JSON is directly a list of Face class instances, so the FaceJson type is not necessary:
List<Face> obj = JsonConvert.DeserializeObject<List<Face>>(contentString);
foreach ( var face in obj )
{
Console.WriteLine( face.faceId );
}

JSON string you shared is not correct. Please check this fiddle.
[
{
"faceId": "f7eda569-4603-44b4-8add-cd73c6dec644",
"faceRectangle": {
"top": 131,
"left": 177,
"width": 162,
"height": 162
}
},
{
"faceId": "f7eda569-4603-44b4-8add-cd73c6dec644",
"faceRectangle": {
"top": 131,
"left": 177,
"width": 162,
"height": 162
}
}
]
Also you are deserializing a List<Face> , you can access it using index only.
UPDATE
You need to deserialize List<Face> not single Face class. It will solve you problem.

Related

Converting JSON to C#

I am trying to get a program I wrote in C# to post to a Slack channel through a Slack App but using formatting suggested here: https://api.slack.com/tools/block-kit-builder
I have this code below which posts to the Slack channel so I know that is working.
{
static void Main(string[] args)
{
PostWebHookAsync();
Console.ReadLine();
}
static async void PostWebHookAsync()
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "my-webhook-link"))
{
string jsonValue = JsonConvert.SerializeObject(new
{
type = "section",
text = "Some text \n new line \t tab",
}
);
Console.WriteLine(jsonValue);
Type valueType = jsonValue.GetType();
if (valueType.IsArray)
{
jsonValue = jsonValue.ToString();
Console.WriteLine("Array Found");
}
request.Content = new StringContent(jsonValue, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
}
}
}
}
Which returns:
{"type":"section","text":"Some text \n new line \t tab"}
Now I want to POST this
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "This is a mrkdwn section block :ghost: *this is bold*, and ~this is crossed out~, and <https://google.com|this is a link>"
}
}
But I am struggling to understand what to change this block of code for
string jsonValue = JsonConvert.SerializeObject(new
{
type = "section",
text = "Some text \n new line \t tab",
}
You need to do the following, the text property is an object, so just create another anonymous object.
string jsonValue = JsonConvert.SerializeObject(new
{
type = "section",
text = new
{
type = "mrkdwn",
text = "This is a mrkdwn section block :ghost: *this is bold*, and ~this is crossed out~, and <https://google.com|this is a link>"
}
}

Fire TriggeredSends from ExactTarget's API using HttpClient REST

I've read along the way that Salesforce (I'm extremely new to this 3rd party platform) has a FUEL SDK which one can use instead of the version (using HttpClient -- REST instead of SOAP).
Please correct me if using FUEL SDK is the only way to go about requesting Salesforce's endpoints. Currently I am attempting to hit ExactTargets's API endpoints using HttpClient. These are the tutorials I've been basing my code off of:
https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/messageDefinitionSends.htm
https://developer.salesforce.com/docs/atlas.en-us.mc-getting-started.meta/mc-getting-started/get-access-token.htm
Wanted Result:
To be able to request a Triggered Send email based off a template inside of ExactTarget.
Problem:
The Salesforce endpoint continuously returns a 404. I am able to receive the authorization token successfully. The GetAccessToken method is omitted for brevity
https://www.exacttargetapis.com/messaging/v1/messageDefinitionSends/key:MyExternalKey/send
I do not understand why the 2nd POST request to //www.exacttargetapis.com/..... returns a 404 but the authorization works. This leads me to believe that I do not have to use the FUEL SDK to accomplish triggering a welcome email.
Code:
private const string requestTokenUrl = "https://auth.exacttargetapis.com/v1/requestToken";
private const string messagingSendUrl = "https://www.exacttargetapis.com/messaging/v1/messageDefinitionSends";
private string exactTargetClientId = ConfigurationManager.AppSettings["ExactTargetClientId"];
private string exactTargetClientSecret = ConfigurationManager.AppSettings["ExactTargetClientSecret"];
private string TriggerEmail(User model, string dbName)
{
var etExternalKeyAppSetting = ConfigurationManager.AppSettings.AllKeys.FirstOrDefault(x => x.Equals(dbName));
if (etExternalKeyAppSetting != null)
{
string etExternalKey = ConfigurationManager.AppSettings[etExternalKeyAppSetting];
HttpClient client = new HttpClient
{
BaseAddress = new Uri(string.Format(#"{0}/key:{1}/send", messagingSendUrl, etExternalKey)),
DefaultRequestHeaders =
{
Authorization = new AuthenticationHeaderValue("Bearer", this.GetAccessToken())
}
};
try
{
var postData = this.CreateExactTargetPostData(model.Email, etExternalKey);
var response = client.PostAsync(client.BaseAddress
, new StringContent(JsonConvert.SerializeObject(postData).ToString()
, Encoding.UTF8
, "application/json")).Result;
// get triggered email response
if (response.IsSuccessStatusCode)
{
dynamic result = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
}
}
catch (Exception ex)
{
string message = ex.Message;
}
}
return "testing";
}
private object CreateExactTargetPostData(string email, string extKey)
{
var fromData = new
{
Address = ConfigurationManager.AppSettings["AwsSenderEmail"],
Name = "Test"
};
var subscriberAttributes = new { };
var contactAttributes = new
{
SubscriberAttributes = subscriberAttributes
};
var toData = new
{
Address = email,
//SubscriberKey = extKey,
//ContactAttributes = contactAttributes
};
var postData = new
{
From = fromData,
To = toData
};
return postData;
}
I have also tried using Advanced REST Client using the following:
URL:
https://www.exacttargetapis.com/messaging/v1/messageDefinitionSends/key:MyExternalKey/send
POST
Raw Headers:
Content-Type: application/json
Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Raw Payload:
{
"From": {
"Address": "code#exacttarget.com",
"Name": "Code#"
},
"To": {
"Address": "example#example.com",
"SubscriberKey": "example#example.com",
"ContactAttributes": {
"SubscriberAttributes": {
"Region": "West",
"City": "Indianapolis",
"State": "IN"
}
}
},
"OPTIONS": {
"RequestType": "ASYNC"
}
}
Issue was my App in the AppCenter was pointing to the incorrect login for MarketingCloud =(

Error in Set and Unset watermark Request using Youtube Data API V3

I am using
IDE : VS2012
Framework : 4.0
Google API: Youtube Data V3
Authentication: Outh 2.0
I am using Youtube Data API V3 to set watermark on youtube video . Here is my code
**my fiddler request** is : POST https://www.googleapis.com/youtube/v3/watermarks/set?channelId=UCyAn2aVZWNAugdlckOJKG5A
and my content body :
{
"position": {
"cornerPosition": "topRight",
"type": "corner"
},
"timing": {
"durationMs": "50000",
"offsetMs": "1000",
"type": "offsetFromStart"
},
"targetChannelId": "UCyAn2aVZWNAugdlckOJKG5A"
}
i am passing image content with stream object with set method ..
and Response is: Value cannot be null Parameter name: baseUri
public async Task setwatermark()
{
InvideoBranding ib = new InvideoBranding();
InvideoTiming it = new InvideoTiming();
InvideoPosition ip = new InvideoPosition();
Stream stream = null;
it.Type = "offsetFromStart";
it.OffsetMs = 1000;
it.DurationMs = 50000;
ip.Type = "corner";
ip.CornerPosition = "topRight";
string filepath = Server.MapPath("~/Images/orderedList0.png");
ib.TargetChannelId = "UCyAn2aVZWNAugdlckOJKG5A";
// ib.ImageUrl = filepath;
ib.Position = ip;
ib.Timing = it;
using (var fileStream = new FileStream(filepath, FileMode.Open))
{
stream = (Stream)fileStream;
var setrequest = youtubeService.Watermarks.Set(ib, "UCyAn2aVZWNAugdlckOJKG5A",stream,"image/*");
var resp =await setrequest.UploadAsync();
}
Below code is for unset watermarks using YouTube Data API V3.
It is response with --Error 503-backend error.
Fiddler Request :POST https://www.googleapis.com/youtube/v3/watermarks/unset?channelId=UCyAn2aVZWNAugdlckOJKG5A
**Fiddler response** :{
"error": {
"errors": [
{
"domain": "global",
"reason": "back end Error",
"message": "Back end Error"
}
],
"code": 503,
"message": "Back end Error"
}
}
private void Unsetwatermark()
{
var unsetrequest = youtubeService.Watermarks.Unset("UCyAn2aVZWNAugdlckOJKG5A");
var searchListResponse = unsetrequest.Execute();
}
Please tell me what i am doing wrong for both above mentioned api request ..

Retrieving the Request Payload values from a HTTPRequest in c#

I am attempting to implement my own LRS for saving TinCanAPI statements and in order to do this I need to retrieve the values sent in the Request Payload which stores the details of the learning activity statement.
When viewing my WebAPI call in developer tools I can see the required values but I have been unable to find them using the Request object.
How Can I retrieve the Request Payload variables from the Request object? I have tried the request object and looked in the Content and Properties fields but I cannot seem to see a Request Payload property to reference in C#. My payload looks as follows:
{
"id": "d3d9aa2a-5f20-4303-84c3-1f6f5b4e9236",
"timestamp": "2014-06-26T11:00:41.432Z",
"actor": {
"objectType": "Agent",
"mbox": "mailto:name#company.com",
"name": "My Name"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/attempted",
"display": {
"und": "attempted"
}
},
"context": {
"extensions": {
"http://tincanapi.com/JsTetris_TCAPI/gameId": "5686f104-3301-459d-9487-f84af3b3915c"
},
"contextActivities": {
"grouping": [
{
"id": "http://tincanapi.com/JsTetris_TCAPI",
"objectType": "Activity"
}
]
}
},
"object": {
"id": "http://tincanapi.com/JsTetris_TCAPI",
"objectType": "Activity",
"definition": {
"type": "http://adlnet.gov/expapi/activities/media",
"name": {
"en-US": "Js Tetris - Tin Can Prototype"
},
"description": {
"en-US": "A game of tetris."
}
}
}
}
I have tried using:
var test1 = Request.ToString(); **EMPTY STRING**
var test1 = Request.Content.ReadAsStringAsync().Result; **EMPTY STRING**
var test2 = Request.Content.ReadAsFormDataAsync().Result; **THROWS FORMATTER ERROR DESPITE config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); added in the webapiconfig.cs
I was able to retrieve the sent statement values by changing my WebAPI controller as follows:
public void Put([FromBody]TinCan.Statement statement)
{
var actor = statement.actor;
var context = statement.context;
var target = statement.target;
var timestamp = statement.timestamp;
var verb = statement.verb;
...................
try {
//String payloadRequest = getBody(request);
// System.out.println("payloadRequest : "+payloadRequest);
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String data = buffer.toString();
System.out.println("payloadRequest : "+data);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Try this:
var value = Request["var_name"];

converting the http request to use webclient

I'm developing windows phone 8 application.. i cannot use the dll using system.net.httpwebrequest; in windows phone 8, so i need to converet the http request to webclient can any one suggest how to convert it..?
private HttpWebResponse GetHttpWebResponse(HttpWebRequest webRequest)
{
HttpWebResponse response;
try
{
response = (HttpWebResponse)webRequest.GetResponse();
//GetResponse() produce error that System.Net.HttpRequest dll is missing,
//so im in need to conertr the http request to webclient.
}
catch (WebException we)
{
response = (HttpWebResponse)we.Response;
}
return response;
}
my complete Json data
[
{
"id": 01,
"address": "12asdf",
"city": " chennai",
"contact1": "",
"contact2": "",
"country": " india",
"description": "",
"name": " david",
"region": "",
"state": " 033",
"website": "",
"image": "",
"PrayerTime": {
"id": 01,
"PrayerTime1": "00:52",
"PrayerTime2": "21:04",
"PrayerTime3": "12:27",
"PrayerTime4": "05:35",
"PrayerTime5": "21:04",
"created_at": null,
"PrayerTime6": "04:01",
"updated_at": null,
"organization_id": 001
}
},.............
}
I recommend that you use the HttpClient instead (nuget package), it's more convenient and is supported also on WinRT.
Here is an example from trying to fetch geo coded data from social medias (which is irrelevant itself, but its a real world example :) , using HttpClient
(you need Newtonsoft.Json to use JObject/JArray)
You can probably waive the part where I add the DefaultRequestHeaders in your own call
using (HttpClient client = new HttpClient())
{
string url = mediaConfig.RequestUrl + String.Format(mediaConfig.GeoCodeStringFormat, lat, lon, distance);
if (mediaConfig.MediaName == "Twitter")
client.DefaultRequestHeaders.Add(mediaConfig.BearerTokenParamName, mediaConfig.BearerToken);
else if (mediaConfig.MediaName == "Instagram")
url = url + "&" + mediaConfig.BearerTokenParamName + "=" + mediaConfig.BearerToken;
else if (mediaConfig.MediaName == "GooglePlaces")
url = url + "&" + mediaConfig.BearerTokenParamName + "=" + mediaConfig.BearerToken;
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
}
responseString = await response.Content.ReadAsStringAsync();
Make sure your method signature has the async keyword, if you would to return "responseString":
public async Task<string> methodname(... params ...
to "consume" this method from a sync method:
var mytask = methodname();
mytask.ContinueWith(c =>
{
var jsonResponse = JObject.Parse(c.Result);
// or JArray
var jsonResponseArray = JArray.Parse(c.Result);
foreach (var item in jsonResponseArray)
{
var id = item.SelectToken("id").ToString();
// and so on...
}
var selectSomething = jsonResponse.SelectToken("somethinghere");
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// do your ui tasks, navigate etc...
});
});

Categories