Before I get into the code let me explain what i'm trying to do. It's a simple checklist against an API, the api has a limit and I figured a way to break the limit with changing my ip easily from my router. It works great most of the time but at some point after re-connecting successfully the worker stops and I have to click the button again.
Here's the code, first the Form class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MyNameChecker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void chk_Click(object sender, EventArgs e)
{
if (!checkNames.IsBusy)
{
checkNames.RunWorkerAsync();
}
}
int last = 0;
private void checkNames_DoWork(object sender, DoWorkEventArgs e)
{
string namesList = "";
string[] namesArray;
if (names.InvokeRequired) names.Invoke(new MethodInvoker(delegate { namesList = names.Text; }));
else namesList = names.Text;
if (!string.IsNullOrEmpty(namesList))
{
namesArray = namesList.Replace("\r","").Split('\n');
while (last < namesArray.Length)
{
string tempStr = NameChecker.check(namesArray[last].Replace("\r", "").Replace("\n", ""));
if (tempStr == "available")
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Names\available.txt", true)) file.WriteLine(namesArray[last]);
last++;
}
else if (tempStr == "unavailable" || tempStr == "skep")
{
last++;
}
else
{
while(!NameChecker.reconnect());
}
}
if (last >= namesArray.Length) last = 0;
}
}
}
}
Second MyNameChecker class:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
namespace MyNameChecker
{
class NameChecker
{
public static string check(string name)
{
if (string.IsNullOrEmpty(name)) return "skep";
string url = "https://example.com/api";
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.AllowAutoRedirect = false;
webRequest.Method = "POST";
webRequest.KeepAlive = true;
webRequest.ContentType = "application/json; charset=UTF-8";
ASCIIEncoding encoding = new ASCIIEncoding();
string stringData = "{\"name\":\"" + name + "\"}";
byte[] data = encoding.GetBytes(stringData);
webRequest.ContentLength = data.Length;
webRequest.GetRequestStream().Write(data, 0, data.Length);
webRequest.Timeout = 60000;
try
{
// Get the response ...
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
{
if (string.IsNullOrEmpty(webResponse.Headers["RequestNum"])) return "retry";
else return status(webResponse);
}
}
catch (WebException ex)
{
var res = (HttpWebResponse)ex.Response;
if (string.IsNullOrEmpty(res.Headers["RequestNum"])) return "retry";
else return status(res);
}
catch (Exception ex)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Names\Exceptions.txt", true)) file.WriteLine(ex.Message);
return "retry";
}
return "retry";
}
private static string status(HttpWebResponse res)
{
switch((int)res.StatusCode)
{
case 201:
return "available";
case 400:
return "unavailable";
default:
return "retry";
}
}
public static bool reconnect()
{
string url = "http://router.lan/cgi/b/is/_pppoe_/ov/?be=0&l0=1&l1=1&name=Internet";
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.AllowAutoRedirect = false;
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.KeepAlive = true;
System.Net.ServicePointManager.Expect100Continue = false;
ASCIIEncoding encoding = new ASCIIEncoding();
string stringData = "0=12&1=Internet&32=1";
byte[] data = encoding.GetBytes(stringData);
webRequest.ContentLength = data.Length;
webRequest.GetRequestStream().Write(data, 0, data.Length);
webRequest.Timeout = 25000;
try
{
// Get the response ...
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
{
// Get the body stream
string body = new System.IO.StreamReader(webResponse.GetResponseStream()).ReadToEnd();
if (body.Contains("Uptime:")) return true;
return false;
}
return false;
}
catch (WebException ex)
{
var res = (HttpWebResponse)ex.Response;
string body = new System.IO.StreamReader(res.GetResponseStream()).ReadToEnd();
if (body.Contains("Uptime:")) return true;
return false;
}
catch (Exception ex)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Names\Exceptions.txt", true)) file.WriteLine(ex.Message);
return false;
}
return false;
}
}
}
I tried everything I could from increasing the timeout to catch all exceptions but there's no exception recorded? I'm unable to figure this problem. Usually I go to sleep and let it do it's work but this is just not working as expected.
BTW I used fiddler to debug the requests and there was an odd header Expect: 100-continue i don't know if this has anything to do with the breaking but I thought it's better to mention it.
Related
I am trying to Access the private Poloniex trading API in Unity C# but am getting the error "invalid command" I have my API Key and Secret authorized on Poloniex for the Trading API but can't seem to get access with my current code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Security.Cryptography;
public class PolonScript : MonoBehaviour {
public TextMesh OutputText;
const string _apiKey = "---Key---";
const string _apiSecret = "---secret---";
void Start () {
string nonce = DateTime.Now.ToString("HHmmss");
string myParam = "command=returnBalances&nonce=" + nonce;
const string WEBSERVICE_URL = "https://poloniex.com/tradingApi";
try
{
var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
if (webRequest != null)
{
webRequest.Method = "POST";
webRequest.Timeout = 12000;
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Headers.Add("Key", _apiKey);
webRequest.Headers.Add("Sign", genHMAC(myParam));
webRequest.Headers.Add("command", "returnBalances");
webRequest.Headers.Add("nonce", nonce.ToString());
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
var jsonResponse = sr.ReadToEnd();
OutputText.text = jsonResponse.ToString();
}
}
}
}
catch (Exception ex)
{
OutputText.text = ex.ToString();
}
} //end-of-start()
Here is my current signing method which I am quite sure has a mistake (Human error) within, am I doing something wrong obliviously here?
private string genHMAC(string message)
{
byte [] APISecret_Bytes = System.Text.Encoding.UTF8.GetBytes(_apiSecret);
byte [] MESSAGE_Bytes = System.Text.Encoding.UTF8.GetBytes(message);
var hmac = new HMACSHA512(APISecret_Bytes);
var hashmessage = hmac.ComputeHash(MESSAGE_Bytes);
var sign = BitConverter.ToString(hashmessage).Replace("-", "").ToLower();
return sign;
}
}
Poloniex Command should not be sent in the header, you should send it as a POST parameter, that's why it's responding "invalid command". Take a look at this answer to see how you send POST parameters in c#:How to add parameters into a WebRequest?
Here's an example of how your Start method should look like:
void Start()
{
string nonce = DateTime.Now.ToString("HHmmss");
string myParam = "command=returnBalances&nonce=" + nonce;
const string WEBSERVICE_URL = "https://poloniex.com/tradingApi";
try
{
var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
if (webRequest != null)
{
webRequest.Method = "POST";
webRequest.Timeout = 12000;
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Headers.Add("Key", _apiKey);
webRequest.Headers.Add("Sign", genHMAC(myParam));
byte[] dataStream = Encoding.UTF8.GetBytes($"command=returnBalances&nonce={nonce.ToString()}");
webRequest.ContentLength = dataStream.Length;
Stream newStream = webRequest.GetRequestStream();
newStream.Write(dataStream, 0, dataStream.Length);
newStream.Close();
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
var jsonResponse = sr.ReadToEnd();
OutputText.text = jsonResponse.ToString();
}
}
}
}
catch (Exception ex)
{
OutputText.text = ex.ToString();
}
}
I'm doing some research, and I want to logging into the ecac site using my company's certificate ... using Chrome I can access the system without any problem because chrome asks for the certificate to authenticate the login. I tried to implement a small test crawler, where I put my certificate in the request, but, the government website always returns error ... So I tried to use selenium with the chrome driver to login, but with that it is necessary that I select the certificate manually, and my idea is to do this automatically.
My test source is:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace TestCrawler
{
class Program
{
static void Main(string[] args)
{
string host = #"https://cav.receita.fazenda.gov.br/autenticacao/login";
string certName = #"certificado.pfx";
string password = #"senha";
try
{
X509Certificate2 certificate = new X509Certificate2(certName, password);
ServicePointManager.CheckCertificateRevocationList = false;
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
ServicePointManager.Expect100Continue = true;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(host);
req.PreAuthenticate = true;
req.AllowAutoRedirect = true;
req.ClientCertificates.Add(certificate);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
string postData = "login-form-type=cert";
byte[] postBytes = Encoding.UTF8.GetBytes(postData);
req.ContentLength = postBytes.Length;
Stream postStream = req.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
string line = reader.ReadLine();
while (line != null)
{
Console.WriteLine(line);
line = reader.ReadLine();
}
}
stream.Close();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
When analyzing the source of the ecac site, I have identified that in the login button by the certificate, a JS code is executed
onclick="javascript:document.loginCert.submit(); return false;
My another test:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
namespace TestCrawler
{
class Program
{
private static string host = #"https://cav.receita.fazenda.gov.br/";
private static string certName = #"certificado.pfx";
private static string password = #"senha";
static async void Login()
{
X509Certificate2 certificate = new X509Certificate2(certName, password);
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(certificate);
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri(host);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
// New code:
using (HttpResponseMessage response = await client.GetAsync("autenticacao/Login/Certificado"))
{
using (HttpContent content = response.Content)
{
string result = await content.ReadAsStringAsync();
}
}
}
}
static void Main(string[] args)
{
Login();
Console.ReadLine();
}
}
}
Following code returns entire JSON objects but I need to Filter to some specific Object, for example I need to get only the "layers" or tiltle can you please let me know how to do this is C#?
Do I have to create an HttpWebRequestobject for this? if so where should I pass the requested data?
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Water_Network/FeatureServer?f=pjson");
Console.WriteLine(json);
}
I already tried this but it is also returning everything
class Program
{
private const string URL = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Water_Network/FeatureServer?f=pjson";
private const string DATA = #"{{""layers"":""Layers""}}";
static void Main(string[] args)
{
CreateObject();
}
private static void CreateObject()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = DATA.Length;
using (Stream webStream = request.GetRequestStream())
using (StreamWriter requestWriter = new StreamWriter(webStream, System.Text.Encoding.ASCII))
{
requestWriter.Write(DATA);
}
try
{
WebResponse webResponse = request.GetResponse();
using (Stream webStream = webResponse.GetResponseStream())
{
if (webStream != null)
{
using (StreamReader responseReader = new StreamReader(webStream))
{
string response = responseReader.ReadToEnd();
Console.WriteLine(response);
Console.ReadLine();
}
}
}
}
catch (Exception e)
{
Console.WriteLine("-----------------");
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
}
If you need the info related to the layers array object then you can use following code
using (var wc = new WebClient())
{
string json = wc.DownloadString("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Water_Network/FeatureServer?f=pjson");
dynamic data = Json.Decode(json);
Console.WriteLine(data.layers[0].id);
Console.WriteLine(data.layers[0].name);
Console.WriteLine(data.documentInfo.Title);
}
I have to Send HTTP request to GET the initial page then, GET the HTTP response and do a check to see if it is a 200 response code. All this has to be saved into a .csv file, four times per website.
This is how far I got:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HTTPrequestApp
{
class Program
{
static void Main(string[] args)
{
var lstWebSites = new List<string>
{
"www.mearstransportation.com",
"www.amazon.com",
"www.ebay.com",
"www.att.com",
"www.verizon.com",
"www.sprint.com",
"www.centurylink.com",
"www.yahoo.com"
};
string filename = #"RequestLog.txt";
{
using (var writer = new StreamWriter(filename, true))
{
foreach (string website in lstWebSites)
{
for (var i = 0; i < 4; i++)
{
MyWebRequest request = new MyWebRequest();
request.Request();
}
}
}
}
}
}
}
I still have to do the GET request in another class I created called MyWebRequest.cs
Please help me.
In your MyWebRequest class do the following (you will also need to pass the website url string to the MyWebRequest, but I'll just do it explicitly):
HttpWebResponse response = null;
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.google.com/thisisadeadlink");
request.Method = "GET";
response = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
Console.Write(sr.ReadToEnd());
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
response = (HttpWebResponse)e.Response;
Console.Write("Errorcode: {0}", (int)response.StatusCode);
}
else
{
Console.Write("Error: {0}", e.Status);
}
}
finally
{
if (response != null)
{
response.Close();
}
}
This should catch if server failed and response.StatusCode is not 200.
Since your MyWebRequest is using HttpWebRequest, the Request method can return HttpWebResponse if it has the URL as a parameter like this:
public class MyWebRequest
{
public HttpWebResponse Request(string url)
{
HttpWebResponse response = null;
try
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
response = (HttpWebResponse)httpWebRequest.GetResponse();
}
catch (WebException ex)
{
// Handle exception
}
return response;
}
}
and it can be called in the for loop like this:
HttpWebResponse response = request.Request("http://" + website);
if ((response != null) && (response.StatusCode == HttpStatusCode.OK))
{
// Write .csv file
}
Here is my proxy code.
[Runtime.InteropServices.DllImport("wininet.dll", SetLastError = true)]
private static bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);
public struct Struct_INTERNET_PROXY_INFO
{
public int dwAccessType;
public IntPtr proxy;
public IntPtr proxyBypass;
}
private void UseProxy(string strProxy)
{
const int INTERNET_OPTION_PROXY = 38;
const int INTERNET_OPEN_TYPE_PROXY = 3;
Struct_INTERNET_PROXY_INFO struct_IPI = default(Struct_INTERNET_PROXY_INFO);
struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
struct_IPI.proxy = Marshal.StringToHGlobalAnsi(strProxy);
struct_IPI.proxyBypass = Marshal.StringToHGlobalAnsi("local");
IntPtr intptrStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI));
Marshal.StructureToPtr(struct_IPI, intptrStruct, true);
bool iReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY, intptrStruct, System.Runtime.InteropServices.Marshal.SizeOf(struct_IPI));
}
private void Button1_Click(System.Object sender, System.EventArgs e)
{
Label4.Text = (TextBox1.Text + ":" + TextBox2.Text);
}
This code works fine with a windows from app. I tried using it in a console app and checked my ip but it did not work. Here is how i used it in a console app,
static void Main()
{
Console.WriteLine("Ip before Proxy /r/n");
HTTPGet req = new HTTPGet();
req.Request("http://checkip.dyndns.org");
string[] a = req.ResponseBody.Split(':');
string a2 = a[1].Substring(1);
string[] a3 = a2.Split('<');
string a4 = a3[0];
Console.WriteLine(a4);
UseProxy("219.93.183.106:8080");
Console.WriteLine("Ip after Proxy /r/n");
HTTPGet req1 = new HTTPGet();
req1.Request("http://checkip.dyndns.org");
string[] a1 = req1.ResponseBody.Split(':');
string a21 = a1[1].Substring(1);
string[] a31 = a21.Split('<');
string a41 = a31[0];
Console.WriteLine(a41);
Console.ReadLine();
}
HTTPGet is a class i got from : Get public/external IP address?
I want the proxy to work with the console app. I am not sure what is the problem
I will also run multiple instances of program so I want each console using one proxy and it should only affect the browsing of the console and not whole computer.
Proxies will have no authentication.
Here is my own HTTPBase class which handles all the http requests for the whole app,
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Web;
using System.Runtime.InteropServices;
public class HTTPBase
{
private CookieContainer _cookies = new CookieContainer();
private string _lasturl;
private int _retries = 3;
private string _useragent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; FunWebProducts; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; InfoPath.1)";
public HTTPBase()
{
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
}
public void ClearCookies()
{
this._cookies = new CookieContainer();
}
public static string encode(string str)
{
// return System.Net.WebUtility.HtmlEncode(str);
return HttpUtility.UrlEncode(str);
//return str;
}
public string get(string url)
{
for (int i = 0; i < this._retries; i++)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = this._useragent;
request.CookieContainer = this._cookies;
if (this._lasturl != null)
{
request.Referer = this._lasturl;
}
else
{
request.Referer = url;
}
this._lasturl = url;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
catch (Exception exception)
{
if ((i + 1) == this._retries)
{
throw exception;
}
}
}
throw new Exception("Failed");
}
public string post(string url, string postdata)
{
for (int i = 0; i < this._retries; i++)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/x-www-form-urlencoded";
if (this._lasturl != null)
{
request.Referer = this._lasturl;
}
else
{
request.Referer = url;
}
this._lasturl = url;
request.Method = "POST";
request.UserAgent = this._useragent;
request.CookieContainer = this._cookies;
request.ContentLength = postdata.Length;
using (Stream stream = request.GetRequestStream())
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write(postdata);
}
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream stream2 = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream2))
{
return reader.ReadToEnd();
}
}
}
catch (Exception exception)
{
if (this._lasturl.Contains("youtuberender.php"))
{
return "bypassing youtube error";
}
if ((i + 1) == this._retries)
{
throw exception;
}
}
}
throw new Exception("Failed");
}
public string post(string url, string postdata, string referer)
{
for (int i = 0; i < this._retries; i++)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/x-www-form-urlencoded";
request.Referer = referer;
this._lasturl = url;
request.Method = "POST";
request.UserAgent = this._useragent;
request.CookieContainer = this._cookies;
request.ContentLength = postdata.Length;
using (Stream stream = request.GetRequestStream())
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write(postdata);
}
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream stream2 = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream2))
{
return reader.ReadToEnd();
}
}
}
catch (Exception exception)
{
if (this._lasturl.Contains("youtube.com"))
{
return "bypassing youtube error";
}
if ((i + 1) == this._retries)
{
throw exception;
}
}
}
throw new Exception("Failed");
}
public string XmlHttpRequest(string urlString, string xmlContent)
{
string str = null;
HttpWebRequest request = null;
HttpWebResponse response = null;
request = (HttpWebRequest)WebRequest.Create(urlString);
try
{
byte[] bytes = Encoding.ASCII.GetBytes(xmlContent);
request.Method = "POST";
request.UserAgent = this._useragent;
request.CookieContainer = this._cookies;
request.ContentLength = bytes.Length;
request.Headers.Add("X-Requested-With", "XMLHttpRequest");
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
using (Stream stream = request.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
stream.Close();
}
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
using (Stream stream2 = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream2))
{
str = reader.ReadToEnd();
}
}
}
response.Close();
}
catch (WebException exception)
{
throw new Exception(exception.Message);
}
catch (Exception exception2)
{
throw new Exception(exception2.Message);
}
finally
{
response.Close();
response = null;
request = null;
}
return str;
}
public string UserAgent
{
get
{
return this._useragent;
}
set
{
this._useragent = value;
}
}
}
}
So I want to be able to add the proxy in this code. I will pass a variable from main form which will have the proxy:port format and I want this code to use the proxy. I am new to these proxy things and having some confusions.
I use net framework 4.0 in VS 12.
You can use WebRequest.DefaultWebProxy
WebRequest.DefaultWebProxy = null;
using (WebClient wc = new WebClient())
{
string html = wc.DownloadString("http://checkip.dyndns.org");
Console.WriteLine(XDocument.Parse(html).Root.Element("body").Value);
}
WebRequest.DefaultWebProxy = new WebProxy("219.93.183.106", 8080);
using (WebClient wc = new WebClient())
{
string html = wc.DownloadString("http://checkip.dyndns.org");
Console.WriteLine(XDocument.Parse(html).Root.Element("body").Value);
}
Or you can set proxy explicitly:
using (WebClient wc = new WebClient { Proxy = null })
{
string html = wc.DownloadString("http://checkip.dyndns.org");
Console.WriteLine(XDocument.Parse(html).Root.Element("body").Value);
}
using (WebClient wc = new WebClient { Proxy = new WebProxy("219.93.183.106", 8080) })
{
string html = wc.DownloadString("http://checkip.dyndns.org");
Console.WriteLine(XDocument.Parse(html).Root.Element("body").Value);
}