Converting JSON to C# - 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>"
}
}

Related

Unable to deserialize the JSON Data

I'm currently using an API to grab some player information, which looks like this in raw data form:
{
"response": {
"players": [
{
"steamid": "76561198166559342",
"communityvisibilitystate": 1,
"profilestate": 1,
"personaname": "Stack Overflow",
"commentpermission": 2,
"profileurl": "https://steamcommunity.com/id/stackoverflow/",
"avatar": "https://avatars.akamai.steamstatic.com/8a2e52a3eaefed0296459fa811aasdasd1ce29374.jpg",
"avatarmedium": "https://avatars.akamai.steamstatic.com/8a2e52a3eaefed0296459fa81asdas1ce29374_medium.jpg",
"avatarfull": "https://avatars.akamai.steamstatic.com/8a2e52a3eaefed0296459fa811a61212312e29374_full.jpg",
"avatarhash": "8a2e52a3eaefed02asdasd",
"personastate": 0
}
]
}
}
I am trying to just grab the "personaname" and "avatar" values from my data, which have been quite unsuccessful, so I've tried to objectify the JSON before getting it, which still isn't working:
Models.SteamUser persona;
String httpres;
using (var client = new HttpClient())
{
string steamurl = "MY HIDDEN URL HERE" + s64;
var steamapi = new Uri(steamurl);
var result = client.GetAsync(steamapi).Result.Content.ReadAsStringAsync().Result;
var json = result.ToString();
httpres = json;
var jUser = JObject.Parse(json);
var userData = JsonConvert.DeserializeObject<Models.SteamUser>(jUser["players"]).ToString(); ;
persona = userData;
}
Is there something I'm missing?
To get players from the JSON response, you need jObj["response"]["players"] instead of jObj["players"].
You have to deserialize as List<Models.SteamUser> but not Models.SteamUser as it is an array. Then with IEnumerable.FirstOrDefault() to get the first item of the array.
From the existing code, the userData is string type while persona is List<Models.SteamUser> type. You can't assign userData to persona.
Not suggested using Task.Result as it performs the operation synchronously and waits for the operation to be completed. Hence, it may lead to a deadlock. Instead, works with async/await. Source: What happens while waiting on a Task's Result?
Your code should be looked as below:
Models.SteamUser persona = null;
using (var client = new HttpClient())
{
string steamurl = "MY HIDDEN URL HERE" + s64;
var steamapi = new Uri(steamurl);
var response = await client.GetAsync(steamapi);
var jsonResult = await response.Content.ReadAsStringAsync();
var jObj = JObject.Parse(jsonResult);
var players = JsonConvert.DeserializeObject<List<Models.SteamUser>>(jObj["response"]["players"].ToString());
// Or
// var players = (jObj["response"]["players"] as JArray).ToObject<List<Models.SteamUser>>();
persona = players.FirstOrDefault();
}

How to create exact JSON format to POST method in c# code?

Web Service required this format:
{
"Data":"{\"Name\":\"HelloWorld\",\"BirthDate\":\"2020-03-03\",\"BirthPlace\":\"Nowhere\"}"
}
I required above format to post to web service but my code below doesn't fulfil the format. Please help. I've been using below code to post
var Data = JsonConvert.SerializeObject(new
{
Data = new
{
Name= "HelloWorld",
BirthDate = "2020-03-03",
BirthPlace= "Nowhere"
}
});
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsJsonAsync(apiUrl, Data);
}
If data should contains a string serialization of the real object. You can simply serialize the inner object using the string result as value on your second serialization.
using Newtonsoft.Json;
public static string WrapAndSerialize(object value){
return JsonConvert.SerializeObject(new { Data = JsonConvert.SerializeObject(value) });
}
Using it like:
var myObject=
new
{
Name = "HelloWorld",
BirthDate = "2020-03-03",
BirthPlace = "Nowhere",
};
var Data= WrapAndSerialize(myObject);
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsJsonAsync(apiUrl, Data);
}
LiveDemo
To get the required format do:
string name = "HelloWorld";
string birthdate = "2020-03-03";
string birthplace= "Nowhere";
var jsonData = JsonConvert.SerializeObject(new
{
Data = $"\"Name\"=\"{name}\",\"BirthDate\"=\"{birthdate}\",\"BirthPlace\"=\"{birthplace}\""
});
See it in action: https://dotnetfiddle.net/UBXDtd
The format states that Data shall contain a string. Your code serializes an object with properties, which results in:
{"Data":{"Name":"HelloWorld","BirthDate":"2020-03-03","BirthPlace":"Nowhere"}}
EDIT: While this works, I would recommend #xdtTransform's answer over this. Leaving this here, in case his solution is for some reason not applicable.

The combination of parameters is either not valid or not complete.\r\nParameter name: tagObject VSTS Git API

I try to attach a tag to existing commit using GitHttpClient CreateAnnotatedTagAsync method (Microsoft.TeamFoundation.SourceControl.WebApi). But each time I keep getting error:
The combination of parameters is either not valid or not complete.\r\nParameter name: tagObject
Part of code for adding annotated tag.
GitObject gitObject = new GitObject { ObjectId = commitId, ObjectType = GitObjectType.Commit };
GitAnnotatedTag tagObj = new GitAnnotatedTag
{
Name = tagName.Replace(' ', '_'),
TaggedObject = gitObject,
TaggedBy = new GitUserDate
{
Name = "FirstName LastName",
Email = "someemail#smth.com",
Date = DateTime.Now
},
Message = tagComment
};
GitAnnotatedTag res = gitClient.CreateAnnotatedTagAsync(tagObj, projectName, new Guid(repositoryId)).Result;
Examples of tag objects I tried to send:
Any help would be appreciated.
So I just used API to create tags:
GitAnnotatedTag tag = null;
try
{
var tagObject = new { Name = tagName.Replace(' ', '_'), Message = tagComment, TaggedObjectId = commitId };
StringContent stringContent = new StringContent(JsonConvert.SerializeObject(tagObject),
Encoding.UTF8,
"application/json");
client.DefaultRequestHeaders.Add("Accept", "application/json; charset=utf-8; api-version=3.2-preview.1");
using (HttpResponseMessage response = client.PostAsync(string.Format(createTagUrl, projectId, repositoryId), stringContent).Result)
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
tag = JsonConvert.DeserializeObject<GitAnnotatedTag>(responseBody);
}
}
catch (Exception ex)
{
// Add some error handling here
}
return tag;

How to call static async function in the below code snippet

public static async Task InvokeRequestResponseService( string pstrRequest)
{
ServiceConnect objServiceConnect = new ServiceConnect();
using (var client = new HttpClient())
{
var scoreRequest = new
{
Inputs = new Dictionary<string, InputOutputTable>() {
{
"input1",
new InputOutputTable()
{
ColumnNames = new string[] {"Assignment group", "Short description"},
Values = new string[,] { { "", pstrRequest }, { "", "" }, }
}
},
},
GlobalParameters = new Dictionary<string, string>()
{
}
};
const string apiKey = "Some API Key"; // Replace this with the API key for the web service
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
client.BaseAddress = new Uri("Some Uri");
// WARNING: The 'await' statement below can result in a deadlock if you are calling this code from the UI thread of an ASP.Net application.
// One way to address this would be to call ConfigureAwait(false) so that the execution does not attempt to resume on the original context.
// For instance, replace code such as:
// result = await DoSomeTask()
// with the following:
// result = await DoSomeTask().ConfigureAwait(false)
HttpResponseMessage response = await client.PostAsJsonAsync("", scoreRequest);
}
// I am calling function like this
ServiceConnect.InvokeRequestResponseService("xyz").Wait();
Here Wait() returns viod so I am not able to return anything from here. But I have to add Wait to get task completed.
Could anyone guide how can I get response of function or what is the other way to get the response.
To get response of function change return type to Task<HttpResponseMessage> and return the response.
Given that the response is the only thing that needs the await you can remove the async key work and just return the response task
public static Task<HttpResponseMessage> InvokeRequestResponseService( string pstrRequest)
{
ServiceConnect objServiceConnect = new ServiceConnect();
using (var client = new HttpClient())
{
var scoreRequest = new
{
Inputs = new Dictionary<string, InputOutputTable>() {
{
"input1",
new InputOutputTable()
{
ColumnNames = new string[] {"Assignment group", "Short description"},
Values = new string[,] { { "", pstrRequest }, { "", "" }, }
}
},
},
GlobalParameters = new Dictionary<string, string>()
{
}
};
const string apiKey = "Some API Key"; // Replace this with the API key for the web service
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
client.BaseAddress = new Uri("Some Uri");
// WARNING: The 'await' statement below can result in a deadlock if you are calling this code from the UI thread of an ASP.Net application.
// One way to address this would be to call ConfigureAwait(false) so that the execution does not attempt to resume on the original context.
// For instance, replace code such as:
// result = await DoSomeTask()
// with the following:
// result = await DoSomeTask().ConfigureAwait(false)
return client.PostAsJsonAsync("", scoreRequest);
}
}
With that you can call the function
HttpResponseMessage response = await ServiceConnect.InvokeRequestResponseService("xyz");

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 =(

Categories