I try to load json like this
private async Task<JsonValue> FetchAsync(string url)
{
// Create an HTTP web request using the URL:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "GET";
// Send the request to the server and wait for the response:
using (WebResponse response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (Stream stream = response.GetResponseStream())
{
// Use this stream to build a JSON document object:
JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
Console.Out.WriteLine("Response: {0}", jsonDoc.ToString());
// Return the JSON document:
return jsonDoc;
}
}
}
but in this JsonObject.Load(stream)); I have error:
Error CS0117 'JsonObject' does not contain a definition for 'Load'
As I read on MSDN JsonObject has Load method.
What's wrong in my code?
I know it is late for this post but maybe i can help somebody else.
You should add this line to your project:
using System.Json
Right-click on references and then click add reference. Check System.Json box and then click ok.
Related
I am a very novice C# person so please dont be too hard on me
Im trying to make a post request to MSFLOW from a MSBOT Framwork chatbot. The post request triggers the flow to send an email to chatbot users manager.
I just dont know where to start. I have a basic BOT template from Az but how and where should I put the request
Many thanks
use HttpWebRequest
here is an example of using Http POST request .
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestPostExample
{
public static void Main()
{
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("http://www.example.com/post");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
}
}
}
First, the Flow needs an Request - When an HTTP request is received trigger: https://learn.microsoft.com/en-us/azure/connectors/connectors-native-reqres The trigger can be fired by calling it with any rest client: https://flow.microsoft.com/fr-fr/blog/call-flow-restapi/
Most likely, the bot will make the call to the HTTP Request Trigger when the bot is messaged something specific by a user. Notice the BasicBot.cs file has an OnTurnAsync method. Within here, you can check the .Text property of the activity and if it is "send email" then call the Flow Trigger:
if (activity.Type == ActivityTypes.Message)
{
if(active.Text == "send email")
{
await SendEmail();
}
else
{
// other BasicBot.cs code
}
...
As demonstrated by M.zK, you can use WebRequest in C# to make the Flow Trigger call. You can also use HttpClient:
using (var request = new HttpRequestMessage(HttpMethod.Post, "https://prod-13.westus.logic.azure.com:443/workflows/etc"))
{
var content = new { Properties = new { Property1 = "property 1 value", Property2 = "Property 2 value" } };
var json = JsonConvert.SerializeObject(content);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
await client.SendAsync(request).ConfigureAwait(false);
}
}
I'm trying to get the order book from GDAX (link to documentation of the call) but when doing it from the c# executable I always get Error 400 - Bad request.
When taking the actual URL and pasting it into my browser, it works fine.
String URL = "https://api.gdax.com/products/BTC-USD/book?level=2";
WebRequest request = WebRequest.Create(URL);
WebResponse response = request.GetResponse();
The actual issue with your API call is , the API is expecting a user-agent string while making the request: Below is the code in working condition:
try
{
String URL = "http://api.gdax.com/products/BTC-USD/book?level=2";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.UserAgent = ".NET Framework Test Client";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
}
catch(WebException ex)
{
HttpWebResponse xyz = ex.Response as HttpWebResponse;
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(xyz.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
}
Basically ProtocolError indicates that you have received the response but there is an error related to protocol, which you can observe, when you read the response content from exception. I have added catch to handle the exception and read ex.Response (which is HttpWebResponse) and could see that the API is asking for user-agent to be suppllied while making the call. I got to see the error as "{"message":"User-Agent header is required."}"
You can ignore the code inside the exception block, I used it only to see what is the actual response message, which contains actual error details
Note: I have boxed WebRequest to HttpWebRequest to have additional http protocol related properties and most importantly "UserAgent" property which is not available with the WebRequest class.
You need to Accept the certificarte, Google for access to a https webrequest.
Like this
Before I upgraded to the newest .NetCore I was able to run the HttpWebRequest, add the headers and content Type and pull the stream of the JSON file from Twitch. Since the upgrade this is not working. I receive a Web Exception each time I go to get the response Stream. Nothing has changed with twitch because it still works with the old Bot. The old code is below:
private const string Url = "https://api.twitch.tv/kraken/streams/channelname";
HttpWebRequest request;
try
{
request = (HttpWebRequest)WebRequest.Create(Url);
}
request.Method = "Get";
request.Timeout = 12000;
request.ContentType = "application/vnd.twitchtv.v5+json";
request.Headers.Add("Client-ID", "ID");
try
{
using (var s = request.GetResponse().GetResponseStream())
{
if (s != null)
using (var sr = new StreamReader(s))
{
}
}
}
I have done some research and found that I may need to start using either an HttpClient or HttpRequestMessage. I have tried going about this but when adding headers content type the program halts and exits. after the first line here: (when using HttpsRequestMessage)
request.Content.Headers.ContentType.MediaType = "application/vnd.twitchtv.v5+json";
request.Content.Headers.Add("Client-ID", "rbp1au0xk85ej6wac9b8s1a1amlsi5");
You are trying to add a ContentType header, but what you really want is to add an Accept header (your request is a GET and ContentType is used only on requests which contain a body, e.g. POST or PUT).
In .NET Core you need to use HttpClient, but remember that to correctly use it you need to leverage the use of async and await.
Here it is an example:
using System.Net.Http;
using System.Net.Http.Headers;
private const string Url = "https://api.twitch.tv/kraken/streams/channelname";
public static async Task<string> GetResponseFromTwitch()
{
using(var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.twitchtv.v5+json"));
client.DefaultRequestHeaders.Add("Client-ID", "MyId");
using(var response = await client.GetAsync(Url))
{
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync(); // here we return the json response, you may parse it
}
}
}
I'm using https://timercheck.io/YOURTIMERNAME/60 to create timer, and when the timer end the API Manager to return both an error code and some JSON content
This is the JSON data when timer end:
{"errorMessage":"504: timer timed out"}
When the timer still countdown:
{"timer":"neo308CCEACbid","request_id":"e54f484e-1e64-11e6-9552-3950b2ec2d5c","status":"ok","now":1463732937,"start_time":1463732935,"start_seconds":180,"seconds_elapsed":2,"seconds_remaining":178,"message":"Timer still running"}
Because of the error code, i get error on Visual Studio and App force close on my Android. I only want to get the errorMessage in JSON. I'm using Visual Studio 2015 and Xamarin to make this project.
Thanks in advance
UPDATE:
I'm using this to get web response
private async Task<string> FetchUserAsync(string url)
{
// Create an HTTP web request using the URL:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
// Send the request to the server and wait for the response:
using (WebResponse response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (var sr = new StreamReader(response.GetResponseStream()))
{
string strContent = sr.ReadToEnd();
return strContent;
}
}
}
And call it like this:
CekTimer dataWaktu = JsonConvert.DeserializeObject<CekTimer>(await FetchUserAsync(url));
I assume you are using HttpClient and GetStringAsync, and that the HttpResponse Status code is a 504 too, like in the Json Content.
The shortcut methods like GetStringAsync all make a call to EnsureSuccessStatusCode, which of cause throws an exception on a 504 (see source here).
You can just make a direct get Request:
var client = new HttpClient();
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, yourUri));
var json = await response.Content.ReadAsStringAsync();
I found the answer of my problem, because of webservice return error code, just simply use WebException and get the StatusCode like this :
private async Task<string> FetchUserAsync(string url)
{
try
{
// Create an HTTP web request using the URL:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
// Send the request to the server and wait for the response:
using (WebResponse response = await request.GetResponseAsync())
{
// Get a stream representation of the HTTP web response:
using (var sr = new StreamReader(response.GetResponseStream()))
{
string strContent = sr.ReadToEnd();
return strContent;
}
}
}
catch (WebException e)
{
string a = ((HttpWebResponse)e.Response).StatusCode.ToString();
//Toast.MakeText(this, a, ToastLength.Long).Show();
if (a == "GatewayTimeout")
{
return "{'errorMessage':'504: timer timed out'}";
}
else
{
internetDropDialog();
return "";
}
}
}
I think it isn't the best answer, but it can help you to move on from this problem
I'm new to JSON & am using VS 2013/C#. Here's the code for the request & response. Pretty straightforward, no?
Request request = new Request();
//request.hosts = ListOfURLs();
request.hosts = "www.cnn.com/www.cisco.com/www.microsoft.com/";
request.callback = "process";
request.key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string output = JsonConvert.SerializeObject(request);
//string test = "hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create("http://api.mywot.com/0.4/public_link_json2?);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = output;
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
MessageBox.Show(e.ToString());
}
//response = true.
//no response = false
return true;
}
When I run this, I get a 405 error indicating method not allowed.
It seems to me that there are at least two possible problems here: (1) The WoT API (www.mywot.com/wiki/API) requires a GET request w/ a body, & httpWebRequest doesn't allow a GET in the httpWebRequest.Method; or (2) the serialized string isn't serialized properly.
NOTE: In the following I've had to remove the leading "http://" since I don't have enough rep to post more than 2 links.
It should look like:
api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx
but instead looks like:
api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}.
If I browse to:api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx; I get the expected response.
If I browse to: api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}; I get a 403 denied error.
If I hardcode the request & send as a GET like below:
var httpWebRequest = (HttpWebRequest) WebRequest.Create("api.mywot.com/0.4/public_link_json2? + "test"); it also works as expected.
I'd appreciate any help w/ this & hope I've made the problem clear. Thx.
Looks to me like the problem is that you are sending JSON in the URL. According to the API doc that you referenced, the API is expecting regular URL encoded parameters (not JSON), and it will return JSON to you in the body of the response:
Requests
The API consists of a number of interfaces, all of which are called using normal HTTP GET requests to api.mywot.com and return a response in XML or JSON format if successful. HTTP status codes are used for returning error information and parameters are passed using standard URL conventions. The request format is as follows:
http://api.mywot.com/version/interface?param1=value1¶m2=value2
You should not be serializing your request; you should be deserializing the response. All of your tests above bear this out.