简体   繁体   中英

How to receive json post data in a Webhook

We are using 3rd party api kraken.io to optimize our images.

The results of optimized image is posted in a Webhook .

In their api document it states: After the optimization is over Kraken will POST a message to the callback_url specified in your request in a JSON format application/json .

I am using ngrok to allow remote webhooks to send data to my development machine, using this article.

Results posted to the Callback URL:

HTTP/1.1 200 OK

{
    "id": "18fede37617a787649c3f60b9f1f280d",
    "success": true,
    "file_name": "header.jpg",
    "original_size": 324520,
    "kraked_size": 165358,
    "saved_bytes": 159162,
    "kraked_url": "http://dl.kraken.io/18/fe/de/37617a787649c3f60b9f1f280d/header.jpg"
}

Class to Map

public class KrakenOptimizedResults
{
public string id { get; set; }
public bool success { get; set; }
public string file_name { get; set; }
public int original_size { get; set; }
public int kraked_size { get; set; }
public int saved_bytes { get; set; }
public string kraked_url { get; set; }
}

Action Method

[HttpPost]
public ActionResult OptimizedWebHook()
{

  Request.InputStream.Position = 0;

  string jsonString = new System.IO.StreamReader(Request.InputStream).ReadToEnd();

  KrakenOptimizedResults obj = new JavaScriptSerializer().Deserialize<KrakenOptimizedResults>
  (jsonString);


  return Json(obj);

 }     

But When I debug the received jsonString in Html Visualizer it looks like key and value pairs instead of Json format.

Received Results not Json Formatted:

file_name=header.jpeg&original_size=118066&kraked_size=102459&saved_bytes=15607

I guess the received data content-type: is application/x-www-form-urlencoded .

Why i am receiving key and value pairs instead of Json format ? how can I deserialize Json data in asp.net mvc ?

Co-founder of https://kraken.io here.

There is a glaring omission in our documentation which I will fix today. To get JSON back, you need to set a "json": true flag in the request. Omitting that flag or setting "json": false will return URLEncoded. Example cURL request:

curl http://api.kraken.io/v1/upload -X POST --form data='{"auth":{"api_key":"YOUR_KEY", "api_secret":"YOUR_SECRET"}, "wait": true, "lossy": true, "callback_url": "http://requestb.in/wbhi63wb", "json": true}' --form upload=@test.jpg

Sorry for the inconvenience :-(

Step 1: Create an aspx page. This page must be able to accept HTTP POST request. Step 2: Add this code to get HTTP POST data.File: default.aspx.cs File: default.aspx.cs

var reader = new StreamReader(Request.InputStream);
var json = reader.ReadToEnd();

FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;

ostrm = new FileStream(@"C:\logfile4webhook.txt", FileMode.Append, FileAccess.Write);
writer = new StreamWriter(ostrm);
Console.SetOut(writer);
Console.Write(DateTime.Now + " ");
Console.WriteLine(json.ToString() + " ");
Console.SetOut(oldOut);
writer.Close();
ostrm.Close();

Step 3: Create webhook. This code can be linked to a button on click event.File:default.aspx.cs

AuthenticationDetails auth = new ApiKeyAuthenticationDetails("your api key");
string listID = "";
listID = "your list id";
List list = new List(auth, listID);
List<string> events = new List<string>();
events.Add("Update");

string postback = list.CreateWebhook(events, "URL", "json");

FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;

ostrm = new FileStream(@"C:\logfile4webhook.txt", FileMode.Append, FileAccess.Write);
writer = new StreamWriter(ostrm);
Console.SetOut(writer);
Console.Write(DateTime.Now + " ");
Console.WriteLine(postback + " ");
Console.SetOut(oldOut);
writer.Close();
ostrm.Close();

Step 4: Activate webhook. Copy that webhook id from the text file and past it to the code below. File:default.aspx.cs

AuthenticationDetails auth = new ApiKeyAuthenticationDetails("your api key");
string listID = "";
listID = "your list id";
List list = new List(auth, listID);
list.ActivateWebhook("webhook id");

Step 5: Test weebhook.File: default.aspx.cs

AuthenticationDetails auth = new ApiKeyAuthenticationDetails("your api key");
string listID = "";
listID = "your list id";
List list = new List(auth, listID);
string postback = list.TestWebhook("webhook id").ToString();
FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;

ostrm = new FileStream(@"C:\logfile4webhook.txt", FileMode.Append, FileAccess.Write);
writer = new StreamWriter(ostrm);
Console.SetOut(writer);
Console.Write(DateTime.Now + " ");
Console.WriteLine(postback + " ");
Console.SetOut(oldOut);
writer.Close();
ostrm.Close();

Step 6: Deserialize body of JSON object. We need to create class structure based on JSON data. I put sample json here and it created required classes

public class CustomField
{
    public string Key { get; set; }
    public string Value { get; set; }
}

public class Event
{
    public List<CustomField> CustomFields { get; set; }
    public string Date { get; set; }
    public string EmailAddress { get; set; }
    public string Name { get; set; }
    public string SignupIPAddress { get; set; }
    public string Type { get; set; }
}

public class RootObject
{
    public List<Event> Events { get; set; }
    public string ListID { get; set; }
}

Once you have created your class, append the code from step 2 after

var json = reader.ReadToEnd();

to deserialize and parse json.

RootObject myClass = JsonConvert.DeserializeObject(json);

if (myClass != null)
{
    List<Event> t = myClass.Events;

    string old_email = "", new_email = "";
    old_email = t[0].OldEmailAddress;
    new_email = t[0].EmailAddress;

    //now you can do your logic with old_email and new_email
}

I was able to convert Query String Key and Value pairs to Json Format using this and this post ,there is some delay to convert form Dictionary to Json , so If there is better answers, then do post and advice, below is my solution.

Action Method

[HttpPost]
public ActionResult OptimizedWebHook()
{

 Request.InputStream.Position = 0;

 string data = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
 var dict = HttpUtility.ParseQueryString(data);
 var json = new JavaScriptSerializer().Serialize(dict.AllKeys.ToDictionary(k => k, k =>
            dict[k]));

 KrakenOptimizedResults obj = new JavaScriptSerializer().Deserialize<KrakenOptimizedResults>
                             (json);

  return Json(obj);

}

Recieving JSON formated optimized results from kraken API.

As mentioned by @karim79, To get JSON back, you need to set a "json": true flag in the request.

As Kraken .Net/C# SDK didn't have option to set "json": true, so i have to extend their base class.

Extended Base Class:

public class OptimizeRequestBaseExtended : OptimizeRequestBase,
IOptimizeUploadRequest, IRequest
{

    public OptimizeRequestBaseExtended(Uri callbackUrl)
    {
        CallbackUrl = callbackUrl;
    }

   [JsonProperty("callback_url")]
   public Uri CallbackUrl { get; set; }

   [JsonProperty("json")]
   public bool JsonFormat { get; set; }

}

Request Kraken API:

var callbackUrl = new Uri("http://localhost:0000/Home/OptimizedWebHook");

OptimizeRequestBaseExtended settings = new OptimizeRequestBaseExtended(callbackUrl);

settings.Lossy = true;
settings.JsonFormat = true;

var response = client.Optimize(image: image, filename: filename, optimizeRequest: settings);

Action Method

[HttpPost]
public ActionResult OptimizedWebHook()
{

Request.InputStream.Position = 0;

string jsonString = new System.IO.StreamReader(Request.InputStream).ReadToEnd();


KrakenOptimizedResults obj = JsonConvert.DeserializeObject<KrakenOptimizedResults>
(jsonString);

  return Json(obj);

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM