I have a program that has a lot of HttpWebRequest calls in it. It deals a lot with external API requests to various streaming platforms (Twitch, Hitbox, Beam, YouTube). All of my requests seem to work fine.
Here is an example of one of my requests:
private void save_Click(object sender, RoutedEventArgs e)
{
string postUrl = "https://api.twitch.tv/kraken/channels/" + this.channelID;
string postData = "channel[status]=" + Uri.EscapeDataString(status.Text) +
"&channel[game]=" + Uri.EscapeDataString(game.Text);
byte[] postByte = Encoding.UTF8.GetBytes(postData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);
request.Method = "PUT";
request.Accept = "application/vnd.twitchtv.v5+json";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postByte.Length;
request.Headers.Add("Authorization", "OAuth " + password.Password);
request.Headers.Add("Client-ID", this.clientID);
request.Timeout = 15000;
try
{
Stream putStream = request.GetRequestStream();
putStream.Write(postByte, 0, postByte.Length);
putStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
catch (WebException err)
{
MessageBox.Show("Unable to update channel information:\n" + err.Message);
}
}
However, there is an issue that if a request fails (such as a momentary internet hiccup), and the try-catch responds with an error due to a timeout, then no future HttpWebRequests will work until I restart my program.
This only happens if the error catch is initiated by a timeout.
Is there a reason why this happens and how can I fix it?
It's most likely being caused by resources that are not properly released causing locks.
Change your code to maybe call abort on HttpWebRequest on WebException and maybe also wrap the HttpWebResponse and putStream in a using statement.
private void save_Click(object sender, RoutedEventArgs e)
{
string postUrl = "https://api.twitch.tv/kraken/channels/" + this.channelID;
string postData = "channel[status]=" + Uri.EscapeDataString(status.Text) +
"&channel[game]=" + Uri.EscapeDataString(game.Text);
byte[] postByte = Encoding.UTF8.GetBytes(postData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);
request.Method = "PUT";
request.Accept = "application/vnd.twitchtv.v5+json";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postByte.Length;
request.Headers.Add("Authorization", "OAuth " + password.Password);
request.Headers.Add("Client-ID", this.clientID);
request.Timeout = 15000;
try
{
using (Stream putStream = request.GetRequestStream())
{
putStream.Write(postByte, 0, postByte.Length);
using (var response = (HttpWebResponse) request.GetResponse())
{
//assign the response result to a variable else it's getting disposed
}
}
}
catch (WebException err)
{
request.Abort();
MessageBox.Show("Unable to update channel information:\n" + err.Message);
}
}
Related
I have done a post method to consult the OneSignal API Rest, that when an order has been accepted a notification is sent to the user from the device that placed the order and this is the code line that does not work, and it worked without the small_icon, large_icon and android_accent_color
CODE:
public static void PostNotification(string idPush)
{
var request = WebRequest.Create(AppSettings.OneSignalApi) as HttpWebRequest;
request.KeepAlive = true;
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.Headers.Add("authorization", AppSettings.KeyPush);
byte[] byteArray = Encoding.UTF8.GetBytes("{"
+ $"\"app_id\": \"{AppSettings.PushIDApp}\","
+ "\"small_icon\": \"ic_stat_onesignal_default\","
+ "\"large_icon\": \"ic_onesignal_large_icon_default\","
+ "\"android_accent_color\": \"FFba3870\","
+ "\"contents\": {\"en\": \"Pedido Aceptado\"},"
+ $"\"include_player_ids\": [\"{idPush}\"]" +
"}");
string responseContent = null;
try
{
using (var writer = request.GetRequestStream())
{
writer.Write(byteArray, 0, byteArray.Length);
}
using (var response = request.GetResponse() as HttpWebResponse)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
responseContent = reader.ReadToEnd();
}
}
}
catch (WebException ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(new StreamReader(ex.Response.GetResponseStream()).ReadToEnd());
}
}
I have the icons but it does not show them, it does not send me the notification with it, just removing the following 3 properties, small_icon, large_icon and android_accent_color I do not know if the way I am doing it will be wrong, and I have followed the documentation of the Create Notification.
I have some problems with code. I'm using HttpWebRequest class to do operations
Code as bellow:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 | (SecurityProtocolType)768;
ServicePointManager.Expect100Continue = true;
//ServicePointManager.DefaultConnectionLimit = 5;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverName + authorizePath);
request.Abort();
byte[] bearerMatch = UTF8Encoding.UTF8.GetBytes("username:password");
//request.Proxy = null; //<TNI_20180808
request.Method = "POST";
request.Accept = "application/json";
request.ContentType = "application/json";
request.Timeout = 100;
//request.Headers["Authorization"] = "Bearer " + Convert.ToBase64String(bearerMatch);
string content = String.Format(authorizeBody, login, password);
content = "{" + content + "}";
try
{
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(content);
}
using (WebResponse response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var responseContent = reader.ReadToEnd();
token = responseContent.Replace('"', ' ').Trim();
}
//response.Close();
//request.Abort();
}
}
catch (Exception ex)
{
throw ex;
}
Until third operation everything is okey, unfortunately i don't know what to do. When application is trying to create request third time there is an timeout error:
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
I think that there is an opportunity to solve this with closing request and response in a proper way but i don't know how to do this. After increasing ServicePointManager.DefaultConnectionLimit operations were getting completed correctly.
Can you help me please? How should i abort or close request/response in a good way?
Thank you!
I have the working cURL script:
curl --insecure --data 'username=xxxx&password=xxxx' --dump-header headers https://$ipAddress/login
Trying to do the same thing on Visual C# but it does not work:
private void myExamplelogin(string ipAddress)
{
try
{
string user = xxxx;
string pass = xxxx;
string url = "https://" + ipAddress + "/login";
ServicePointManager.ServerCertificateValidationCallback = (obj, x509Certificate, chain, errors) => true;
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
string postData = "username=" + user + "&password=" + pass;
byte[] byteArray = Encoding.ASCII.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
}
catch (Exception e)
{
MessageBox.Show("error: " + e.Message);
}
}
I am getting "The remote server returned an error: (503) Server Unavailable". But when I try connect manually, the server is OK.
What seems to be wrong with code?
I got one more question related to api I'm working on :p
My problem is that the application i made to read the data works perfectly when the url is all passed, but if i want to pass the general url + parameters it doesn't...
Code with Full URL
private void btn_Api_Click(object sender, EventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://MyIP/api/Employee/?FirstName=Jorge");
request.Method = "POST";
string postData = "";
byte[] data = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.Accept = "application/json";
request.ContentLength = data.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
}
try
{
using (WebResponse response = request.GetResponse())
{
var responseValue = string.Empty;
// grab the response
using (var responseStream = response.GetResponseStream())
{
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
if (responseValue != "")
{
string _txtFileNew = #"C:\Users\Jorge.Leite\Documents\teste\" + txt_First.Text + ".txt"; //+txt_Last.Text + ".txt";
StreamWriter _srEannew = new StreamWriter(_txtFileNew);
_srEannew.WriteLine(responseValue);
_srEannew.Close();
}
}
}
catch (WebException ex)
{
// Handle error
}
Code with Url + parameters later PS: postData is passing the correct string ("?FirstName=Jorge") Jorge is the input Name
private void btn_Api_Click(object sender, EventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("MyIP/api/Employee/");
request.Method = "POST";
string postData = string.Format("?FirstName=" + txt_First.Text);
byte[] data = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.Accept = "application/json";
request.ContentLength = data.Length;
When using this code it has an exception server not found 404
I really don't know what going on with this :\
Thank you in advance
Web API with POST methods do not work as smooth as with GET methods.
Check this other link to know a bit more Reading FromUri and FromBody at the same time
I have a foreach with an "If" and when the condition is true, I do a WebResponse to post my item in a server.
Sometimes the code run for two o more items but other times crashes with the following error:
The remote server returned an error: (407) Proxy Authentication Required.
The code:
WebClient client = new WebClient();
string authInfo = "admin:geoserver";
string address = "http://xxxxxxxx:8080/geoserver/rest/workspaces/";
client.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
WebRequest request = WebRequest.Create(address);
request.ContentType = "text/xml";
request.Method = "POST";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
byte[] bret = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>" + nameWS + "</name></workspace>");
Stream reqstr = request.GetRequestStream();
reqstr.Write(bret, 0, bret.Length);
reqstr.Close();
try
{
WebResponse response = request.GetResponse();
response.Close();
}
My Environment is C# Visual Studio 2010
how often do you call this? as others have suggested it could be that the server is protected from DOS and your requests are seen like that. It's also valuable to dispose immediately all disposable objects with a using block for example. we had some issues once while leaving too many connections open to our web server, internally in our network. You could adjust your code to look like this:
using(var client = new WebClient())
{
string authInfo = "admin:geoserver";
string address = "http://xxxxxxxx:8080/geoserver/rest/workspaces/";
client.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
var request = WebRequest.Create(address);
request.ContentType = "text/xml";
request.Method = "POST";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
byte[] bret = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>" + nameWS + "</name></workspace>");
using (var reqstr = request.GetRequestStream())
{
reqstr.Write(bret, 0, bret.Length);
}
try
{
using (var response = request.GetResponse())
{
// your code here...
}
}
catch (Exception exc)
{
System.Diagnostics.Debug.WriteLine(exc.Message);
}
}