Parse Campaign Monitor's HTTP POST request in JSON using C# - c#

Basically I am working with Campaign Monitor's webhook. I have created an update webhook so when email is updated, Campaign Monitor sends HTTP POST request to the URL I specified. I am having trouble parsing JSON.
Here it is:
POST /subscribe HTTP/1.1
Host: example.com:80
Accept: */*
Content-Type: application/json
{
"Events": [
{
"CustomFields": [
{
"Key": "website",
"Value": "http:\/\/example.org"
}
],
"Date": "2010-12-14 11:32:00",
"OldEmailAddress": "test#example.org",
"EmailAddress": "test#example.org",
"Name": "Test Subscriber Renamed",
"Type": "Update",
"State": "Active"
}
],
"ListID": "96c0bbdaa54760c8d9e62a2b7ffa2e13"
}
I looked at the example http://msdn.microsoft.com/en-ca/library/cc197957(v=vs.95).aspx but couldn't get to work it out.
I would like to get OldEmailAddress, EmailAddress, Type and State. Thanks,
Reference to Campaign Monitor's webhooks https://www.campaignmonitor.com/api/webhooks/#currently_available_webhooks
Thanks,

If I understand correctly you try to get json data from url using C#. First of all you need to get NuGet packages called Newtonsoft.Json
Then you can use this code
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://yourapisite.com"); // Not whole link, just host
var url = "link after your host url";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsStringAsync();
YourClass responsedata = JsonConvert.DeserializeObject<YourClass>(data.Result.ToString());
}
}
Hope this help.
EDIT
First of all,Newtonsoft is a very sensitive about deserialize json.Every json property like CustomField has a property with same name. I edited my answer to your code. Please check and let me know how is working.
I cannot debug this code because I didnt know your api url.
public class Events {
public Events()
{
this.eventData = new List<EventData>();
}
public string ListID { get; set; }
public List<EventData> eventData { get; set; }
}
public class EventData {
public EventData()
{
this.CustomFields = new List<CustomFields>();
}
public DateTime Date { get; set; }
public string OldEmailAddress { get; set; }
public string EmailAddress { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string State { get; set; }
public List<CustomFields> CustomFields { get; set; }
}
public class CustomFields
{
public string Key { get; set; }
public string Value { get; set; }
}

Related

Cognito triggers in C#

I have not found any code examples how to write Cognito trigger in C#. I am particularly interested in pre authentication trigger.
Right now I have the following Lambda function which is set as a pre authentication trigger in Cognito:
public APIGatewayProxyResponse ExampleTrigger(APIGatewayProxyRequest request, ILambdaContext context)
{
context.Logger.LogLine("trigger called");
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK
};
}
However, I receive this error:
{code: "InvalidLambdaResponseException", name: "InvalidLambdaResponseException", message: "Unrecognizable lambda output"}
I think this error is caused because the type APIGatewayProxyResponse is not correct. But what is the correct type?
According to the documentation, handler should expect an object, which represents the following JSON ( including common parameters) :
{
"version": "string",
"triggerSource": "string",
"region": "string",
"userPoolId": "string",
"userName": "string",
"callerContext": {
"awsSdkVersion": "string",
"clientId": "string"
},
"request": {
"userAttributes": {
"string": "string",
. . .
},
"validationData": {
"string": "string",
. . .
},
"userNotFound": boolean
},
"response": {}
}
Also lambda handler should return the same type of object.
Since you are working with C#, probably you can use following classes to deserialize the object. So instead of both APIGatewayProxyRequest and APIGatewayProxyResponse, please use below mentioned Event Type.
public class Event
{
[JsonPropertyName("version")]
public string Version { get; set; }
[JsonPropertyName("region")]
public string Region { get; set; }
[JsonPropertyName("userPoolId")]
public string UserPoolId { get; set; }
[JsonPropertyName("userName")]
public string UserName { get; set; }
[JsonPropertyName("callerContext")]
public CallerContext CallerContext { get; set; }
[JsonPropertyName("triggerSource")]
public string TriggerSource { get; set; }
[JsonPropertyName("request")]
public Request Request { get; set; }
[JsonPropertyName("response")]
public Response Response { get; set; }
}
public class CallerContext
{
[JsonPropertyName("awsSdkVersion")]
public string AwsSdkVersion { get; set; }
[JsonPropertyName("clientId")]
public string ClientId { get; set; }
}
public class Request
{
[JsonPropertyName("userAttributes")]
public Dictionary<string, string> UserAttributes { get; set; }
[JsonPropertyName("validationData")]
public Dictionary<string, string> validationData { get; set; }
}
public class Response
{
}
Let me mention a tip for this kind of scenarios:
Write the handler as:
public dynamic ExampleTrigger(dynamic request, ILambdaContext context)
{
return request
}
Add the following environment variable for lambda.
LAMBDA_NET_SERIALIZER_DEBUG = true
Invoke the Auth flow and check the logs on CloudWatch. You can see the content of the incoming event object.

Problem with posting json to my web-api. How can i solve it

I am new in web api and now make a simple program using .net 3
In my controller i am create simple post method
[HttpPost]
public ActionResult Post(CountryPostRequest countryPostRequest)
{
var savedCity = new City {Name=countryPostRequest.Capital};
var savedRegion = countryDb.Regions.Add(new Region { Name = countryPostRequest.Region });
var savedCountry = countryDb.Countries.Add(new Countrie { Name = countryPostRequest.Name, Region = new Region { Name = countryPostRequest.Region }, Capital = savedCity, AreaSize = countryPostRequest.AreaSize, CountryCode = countryPostRequest.CountryCode, Population = countryPostRequest.Population });
countryDb.SaveChanges();
return RedirectToAction(nameof(Get));
}
This method get a CountryPostRequest. It's looks like that
public class CountryPostRequest
{
public string Name { set; get; }
public string CountryCode { set; get; }
public int Population { set; get; }
public double AreaSize { set; get; }
public string Capital { set; get; }
public string Region { set; get; }
}
Overall i try to post this raw using postman
{
"Name" : "Roman Empire",
"CountryCode" : "RE",
"Population" : 22,
"AreaSize": 22.0,
"Capital" : "Rome",
"Region" : "EU"
}
And postman give me a result:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
"title": "Unsupported Media Type",
"status": 415,
"traceId": "|db653ff6-46b8be8826b56364."
}
Get methods works fine. What's incorrect? Help please
Specifically for your case, since you are using postman to call your API:
You need to set the content-type in postman as JSON (application/json). Go to the body inside your POST request, there you will find the raw option. Right next to it, there will be a drop down, select JSON.

WebApi Not Deserializing Correctly

I'm at my wit's end here. I think I just need another set of eyes.
Method Signature:
public async Task<IHttpActionResult> Post(ApiRequest request)
Model:
[SuppressMessage("ReSharper", "CollectionNeverUpdated.Global")]
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
public class ApiRequest
{
[JsonProperty("allowLoadingToDataWarehouse")]
public bool AllowLoadingToDataWarehouse { get; set; }
[JsonProperty("initialDelay")]
public string InitialDelay { get; set; }
[JsonProperty("reportIds")]
public IEnumerable<string> ReportIds { get; set; }
[JsonProperty("reportTypeDelay")]
public string ReportTypeDelay { get; set; }
[JsonProperty("runType")]
[JsonConverter(typeof(StringEnumConverter))]
public ReportRunType RunType { get; set; }
[JsonProperty("userId")]
public string UserId { get; set; }
[JsonProperty("wwDelay")]
public string WWDelay { get; set; }
[JsonProperty("weeks")]
public IEnumerable<string> Weeks { get; set; }
}
Javascript:
var submitReportRequest = {
userId: userid,
reportIds: reportids,
runType: 'Custom',
weeks: selectedweeks,
initialDelay: $('#InitialDelay').val(),
reportTypeDelay: $('#ReportTypeDelay').val(),
wwDelay: $('#WWDelay').val(),
allowLoadingToDataWarehouse: $('#AllowLoadingToDataWarehouse').val()
};
$.post("/api/SubmitReport", JSON.stringify(submitReportRequest), function (data) {
alert('success');
});
Serialized Json From JavaScript Post:
{
"userId": "30",
"reportIds": [
"59",
"60",
"61",
"62",
"63",
"64"
],
"runType": "Custom",
"weeks": [
"201409",
"201410",
"201411",
"201412"
],
"initialDelay": "00:00:00",
"reportTypeDelay": "00:00:00",
"wwDelay": "00:00:00"
}
Quickwatch of Deserialized Object
Initially I had int and TimeSpan for the Ids and Delays, respectively, and those were not deserializing correctly. So I changed them all to strings, and they're still not deserializing correctly.
What am I doing wrong or missing?
Edit: After trying every combination of attributes, I finally decided to stick it into the Fiddler Composer. And it works. So something must be off with my JavaScript.
Turns out that shorthand JQuery post() method was setting the Content-Type attribute on the Request to application/x-www-form-urlencoded; charset=UTF-8 when it needed to be set to application/json; charset=UTF-8
I found by watching the Network traffic in Chrome, and by changing my javascript to this
answer.

RestSharp - deserialize json response with invalid key name (contains a period )

I've been stuck on this for awhile. I have a JSON response sending me keys that include periods. For example: "cost_center.code"
How can I get this into my object? I'm not getting any errors but the value is just coming in as null and isn't being deserialized into my class.
Here's my classes:
public class Result
{
public string company { get; set; }
public string first_name { get; set; }
public string email { get; set; }
public string employee_id { get; set; }
public string last_name { get; set; }
[DeserializeAs(Name="cost_center.code")]
public string cost_center { get; set; }
}
public class RootObject
{
public List<Result> result { get; set; }
}
Here's the JSON response:
{
"result": [
{
"company": "My Company",
"first_name": "First",
"email": "example#fakeaddress.com",
"employee_id": "123456789",
"last_name": "Last",
"cost_center.code": "12345"
}
]
}
I execute with:
var response = client.Execute<List<RootObject>>(request);
// this returns null
Console.WriteLine(response.Data[0].result[0].cost_center);
// all other values return fine ex:
Console.WriteLine(response.Data[0].result[0].company);
I've tried both with and without the DeserializeAs. I'm not sure its even working. Am I using this property incorrectly? Is it a container issue with the List?
Edited and accepted the answer below to use JsonProperty. For others who may come along this was the solution.
Added JSON.net nuget.
using Newtonsoft.Json;
Set the JsonProperty as described:
[JsonProperty("cost_center.code")]
Changed my execute to:
var response = client.Execute(request);
Then deserialized it like this:
var jsonResponse = JsonConvert.DeserializeObject<RootObject>(response.Content);
Afterwards I can access the value:
Console.WriteLine(jsonResponse.result[0].CostCenter
Do the following with properties having period in their names :
[JsonProperty("cost_center.code")]
public string CostCenter{ get; set; }
It should work
If you want to user RestSharp natively or couldn't get the Newtonsoft.Json.JsonSerializer support to work (which I couldn't), they just added support for proper deserialization of properties with dots in their names as of 106.1.0.
See my response here: Accessing properties with a dot in their name

MVC 4 Web API How to prepare JSON body for Request

Hi I have a function that will expose to the RestAPI. I need to pass in a JSON string to be a defined class. I use the following class for JSON format:
public class Registrant : Guest
{
public int RegistrantID { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public int EventID { get; set; }
public bool IsPrimary { get; set; }
}
And I have the following function in my controller:
public HttpResponseMessage Create(string id, [FromBody]Registrant registrant)
However When I pass in the JSON string the same structure, it could not deserialize correctly.
Is there anything wrong with it?
PS: my JSON string in request body:
{
"RegistrantID":"0",
"Email": "abc#abc.com",
"Phone": "123456789",
"EventID": "8",
"IsPrimary": "true",
"CustomerId": "12345678",
"FirstName": "abc",
"LastName": "def"
}
Update:
The problem is resolved by choosing Content-Type as Application/Json
Also, I took out the quotes on int and bool params it works fine.
Finally the api call look like this in project:
public HttpResponseMessage Create([FromUri]string id, [FromBody]Registrant registrant)

Categories

Resources