WebClient DownloadStringAsync is loading very slowly - c#

Update: I have tried HttpWebRequest and it is also exhibiting the same behaviour.
I'm trying to use WebClient DownloadStringAsync to retrieve some (very small) data in an Outlook add-in (VSTO/.Net 4.0). It's taking about 10-15 seconds before it even makes the request.
Having utilized the powers of google, I was pointed towards the fact that it was trying to pick up the proxy settings, and that I should set these to null. I tried that both in code:
WebClient serviceRequest = new WebClient();
serviceRequest.Proxy = null;
and by adding an App.config file and putting:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy enabled="false">
<proxy/>
<bypasslist/>
<module/>
</defaultProxy>
</system.net>
</configuration>
I added the file through the 'New Item' interface (I'm not sure if its being picked up and utilised).
Neither of these solutions has worked. Is there any things that I could try changing.
The code in question is as follows:
class MyClient
{
string url = "http://192.168.1.99:4567/contact.json?token={0}&email={1}";
WebClient serviceRequest = new WebClient();
public void getContact(string email, DownloadStringCompletedEventHandler methodName)
{
Uri target = new Uri(String.Format(url, "1234", email));
serviceRequest.Proxy = null;
if(serviceRequest.IsBusy)
{
serviceRequest.CancelAsync(); // Changed our mind and switched email
}
serviceRequest.DownloadStringCompleted += methodName;
serviceRequest.DownloadStringAsync(target);
}
}

Discovered what the problem was.
I was working on a Windows 2003 Server Virtual Machine (what I had available). As soon as I installed Windows 7 (and environment) on another VM and tried it the problem vanished.
The server machine does not have IE Enhanced Security turned on.

Related

C# combining GeckoFX + Tor.NET libraries

I am trying to combine GeckoFx library and Tor.NET library.
In my code I do all preparing to use tor network,
ClientCreateParams createParameters = new ClientCreateParams();
createParameters.ConfigurationFile = ConfigurationManager.AppSettings["torConfigurationFile"];
createParameters.ControlPassword = ConfigurationManager.AppSettings["torControlPassword"];
createParameters.ControlPort = Convert.ToInt32(ConfigurationManager.AppSettings["torControlPort"]);
createParameters.DefaultConfigurationFile = ConfigurationManager.AppSettings["torDefaultConfigurationFile"];
createParameters.Path = Path.Combine(root, ConfigurationManager.AppSettings["torPath"]);
createParameters.SetConfig(ConfigurationNames.AvoidDiskWrites, true);
createParameters.SetConfig(ConfigurationNames.GeoIPFile, Path.Combine(root, #"Tor\Data\Tor\geoip"));
createParameters.SetConfig(ConfigurationNames.GeoIPv6File, Path.Combine(root, #"Tor\Data\Tor\geoip6"));
client = Client.Create(createParameters);
<appSettings>
<add key="torConfigurationFile" value=""/>
<add key="torControlPassword" value=""/>
<add key="torControlPort" value="9051"/>
<add key="torDefaultConfigurationFile" value=""/>
<add key="torPath" value="Tor\Tor\tor.exe"/>
</appSettings>
WebBrowser1 is a simple browser and it works with Tor settings.
But browser is GeckoFx and it doesn't work.
webBrowser1.Navigate("https://duckduckgo.com/?q=my+ip&t=h_&ia=answer");
browser.Navigate("https://duckduckgo.com/?q=my+ip&t=h_&ia=answer");
As you see ip should be as on left control.
You can download and test full project from here. It is WinForms project just run "Gecko" project from solution.
Any idea how to set GeckoFx use Tor network?
Or maybe I need somehow setup GeckoFx to use proxy?
//GeckoPreferences.User["network.proxy.type"] = 1;
//GeckoPreferences.User["network.proxy.socks"] = "127.0.0.1";
//GeckoPreferences.User["network.proxy.socks_port"] = 9150;
//GeckoPreferences.User["network.proxy.socks_version"] = 5;
//GeckoPreferences.User["network.proxy.socks_remote_dns"] = true;
VisualStudio 2015.
Thank you.
Have you set any of the Firefox Preferences in your code before initializing the browser?
Try:
GeckoPreferences.Default["network.proxy.type"] = 1;
GeckoPreferences.Default["network.proxy.socks = "127.0.0.1"
GeckoPreferences.Default["network.proxy.socks_port"] = 9050
GeckoPreferences.Default["network.proxy.socks_remote_dns"] = 1
GeckoPreferences.Default["network.proxy.socks_version"] = 5
The network.proxy.type value of 1 is equivalent to "Manual Proxy Configuration" settings.
The following settings configure the SOCKS proxy settings to use Tor at 127.0.0.1:9050 with DNS resolution over SOCKS (Tor).
It seems like this should properly configure GeckoFX to use Tor.
Tor network is not designed for immediate HTTP proxy communications. Instead, TOR.NET implements web proxy, that listens for connections on port 8182 by default.
Also you can assign another port with
client.Proxy.Port = 8042;
Keep in mind, that if you changes proxy port, TOR.NET shutdowns existing http listener, and creates a new one.
So, you need to configure Gecko, to use this web proxy on localhost.

File download async on 8 core CPU [duplicate]

Those "fine" RFCs mandate from every RFC-client that they beware of not using more than 2 connections per host...
Microsoft implemented this in WebClient. I know that it can be turned off with
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>
</configuration>
(found on http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 )
But how can I do it programmatically?
Accordin to
http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx
"Changing the DefaultConnectionLimit property has no effect on existing
ServicePoint objects; it affects only ServicePoint objects that are
initialized after the change. If the value of this property has not been
set either directly or through configuration, the value defaults to the
constant DefaultPersistentConnectionLimit."
I'd like best to configure the limit when I instanciate the WebClient, but just removing this sad limitation programmatically at the start of my programm would be fine, too.
The server I access is not a regular webserver in the internet, but under my control and in the local lan. I want to do API-calls, but I don't use webservices or remoting
for those interested:
System.Net.ServicePointManager.DefaultConnectionLimit = x (where x is your desired number of connections)
no need for extra references
just make sure this is called BEFORE the service point is created as mentioned above in the post.
With some tips from here and elsewhere I managed to fix this in my application by overriding the WebClient class I was using:
class AwesomeWebClient : WebClient {
protected override WebRequest GetWebRequest(Uri address) {
HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address);
req.ServicePoint.ConnectionLimit = 10;
return (WebRequest)req;
}
}
This solution allows you to change the connection limit at any time:
private static void ConfigureServicePoint(Uri uri)
{
var servicePoint = ServicePointManager.FindServicePoint(uri);
// Increase the number of TCP connections from the default (2)
servicePoint.ConnectionLimit = 40;
}
The 1st time anyone calls this FindServicePoint, a ServicePoint instance is created and a WeakReference is created to hold on to it inside the ServicePointManager. Subsequent requests to the manager for the same Uri return the same instance. If the connection isn't used after, the GC cleans it up.
If you find the ServicePoint object being used by your WebClient, you can change its connection limit. HttpWebRequest objects have an accessor to retrieve the one they were constructed to use, so you could do it that way. If you're lucky, all your requests might end up sharing the same ServicePoint so you'd only have to do it once.
I don't know of any global way to change the limit. If you altered the DefaultConnectionLimit early enough in execution, you'd probably be fine.
Alternately, you could just live with the connection limit, since most server software is going to throttle you anyway. :)
We have a situation regarding the above piece of configuration in App.Config
In order for this to be valid in a CONSOLE Application,
we added the System.Configuration reference dll.
Without the reference, the above was useless.

C# SOAP Web Service The server committed a protocol violation. Section=ResponseStatusLine

I have an application that calls a web service... I get an error that I am just pulling the few hairs I have left on my head out maybe someone can help.
Here is the code:
Service_RetrieveIntervalDataserviceagent srv = new Service_RetrieveIntervalDataserviceagent();
srv.Credentials = new NetworkCredential(UserName, Password, Domain);
MDMIntervalDataInput dataInput = new MDMIntervalDataInput();
string Url = srv.Url;
DeviceList deviceList = new DeviceList();
deviceList.Type = DeviceListType.M;
deviceList.DeviceId = "2862,2876,2877".Split(',');
//Setup dataInput
dataInput.ApplicationName = "TestApp";
dataInput.StartDate = DateTime.Now.AddDays(-3).ToString("MM/dd/yyyy");
dataInput.EndDate = DateTime.Now.AddDays(-3).ToString("MM/dd/yyyy");
dataInput.OutputMode = MDMIntervalDataInputOutputMode.Wire;
dataInput.DeviceList = deviceList;
srv.RetrieveIntervalData_V10(dataInput);
I keep getting the error:
The server committed a protocol violation. Section=ResponseStatusLine
I did notice that the URL changes from HTTPS to HTTP could this be the problem?
I also tried adding the following to my config file and it still did not work:
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
How can I fix this?
Here is how I fixed it...
I noticed that the URL was changing from HTTPS to HTTP...The HTTP URL was the culprit so I updated it to manually set the URL and it worked.

Poxy Proxy Problem! c#

Hi
The code below works fine to instruct the system not to use a proxy and to not auto detect one, which causes a delay without the code. However while on a network with a proxy I just get the underlying connection is closed!
So four questions:
Am I specifying the proxy correctly?
If so how do I tell it to use default proxy credentials?
Should the used want to specify credentials how are they set?
How do I set it back to the original state?
if (!Properties.Settings.Default.UseProxyServer){
//set the system not to use a proxy server
//saves the delay seen when browser set to auto detect proxy and not proxy
//is used. This works well!!
WebRequest.DefaultWebProxy = new WebProxy();
}
else{
WebRequest.DefaultWebProxy =
new WebProxy(proxyServerAddress, proxyServerPort);
//proxyServerPort is an int.
//How do I add default credentials??
}
WebClient client = new WebClient();
//specify an encoding for uploading.
client.Encoding = System.Text.Encoding.ASCII;
// Upload the data.
var myReply = client.UploadValues(addressURL, data);
I need to this in code not in the app.config.
Thanks
You can create a Web proxy object
var proxy = new WebProxy("http://server:8080");
proxy.credentials = new system.net.Credentials.DefaultCredenialCache;
proxy.Other properties
You can also create a config
<configuration>
<system.net>
<defaultProxy>
<proxy
usesystemdefaults="true"
proxyaddress="http://192.168.1.10:3128"
bypassonlocal="true"
/>
<bypasslist
<add address="[a-z]+\.contoso\.com" />
</bypasslist>
</defaultProxy>
</system.net>
</configuration>
Try this:
http://weblogs.asp.net/jan/archive/2004/01/28/63771.aspx
You may also want to check this out:
http://geekswithblogs.net/ranganh/archive/2005/08/29/51474.aspx

Is it possible to specify proxy credentials in your web.config?

I need to configure a website to access a webservice on another machine, via a proxy. I can configure the website to use a proxy, but I can't find a way of specifying the credentials that the proxy requires, is that possible? Here is my current configuration:
<defaultProxy useDefaultCredentials="false">
<proxy usesystemdefault="true" proxyaddress="<proxy address>" bypassonlocal="true" />
</defaultProxy>
I know you can do this via code, but the software the website is running is a closed-source CMS so I can't do this.
Is there any way to do this? MSDN isn't helping me much..
Yes, it is possible to specify your own credentials without modifying the current code. It requires a small piece of code from your part though.
Create an assembly called SomeAssembly.dll with this class :
namespace SomeNameSpace
{
public class MyProxy : IWebProxy
{
public ICredentials Credentials
{
get { return new NetworkCredential("user", "password"); }
//or get { return new NetworkCredential("user", "password","domain"); }
set { }
}
public Uri GetProxy(Uri destination)
{
return new Uri("http://my.proxy:8080");
}
public bool IsBypassed(Uri host)
{
return false;
}
}
}
Add this to your config file :
<defaultProxy enabled="true" useDefaultCredentials="false">
<module type = "SomeNameSpace.MyProxy, SomeAssembly" />
</defaultProxy>
This "injects" a new proxy in the list, and because there are no default credentials, the WebRequest class will call your code first and request your own credentials. You will need to place the assemble SomeAssembly in the bin directory of your CMS application.
This is a somehow static code, and to get all strings like the user, password and URL, you might either need to implement your own ConfigurationSection, or add some information in the AppSettings, which is far more easier.
While I haven't found a good way to specify proxy network credentials in the web.config, you might find that you can still use a non-coding solution, by including this in your web.config:
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy proxyaddress="proxyAddress" usesystemdefault="True"/>
</defaultProxy>
</system.net>
The key ingredient in getting this going, is to change the IIS settings, ensuring the account that runs the process has access to the proxy server.
If your process is running under LocalService, or NetworkService, then this probably won't work. Chances are, you'll want a domain account.
You can specify credentials by adding a new Generic Credential of your proxy server in Windows Credentials Manager:
1 In Web.config
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy usesystemdefault="True" />
</defaultProxy>
</system.net>
In Control Panel\All Control Panel Items\Credential Manager >> Add a Generic Credential
Internet or network address: your proxy address
User name: your user name
Password: you pass
This configuration worked for me, without change the code.
Directory Services/LDAP lookups can be used to serve this purpose. It involves some changes at infrastructure level, but most production environments have such provision
Though its very late but it might be helpful for someone looking for solution to the same problem. I came across this question after having same problem. I am giving my solution to the problem, how I made it work.
I created the proxy using using credentials like this,
public class MyProxy : IWebProxy
{
public ICredentials Credentials
{
//get { return new NetworkCredential("user", "password"); }
get { return new NetworkCredential("user", "password","domain"); }
set { }
}
public Uri GetProxy(Uri destination)
{
return new Uri("http://my.proxy:8080");
}
public bool IsBypassed(Uri host)
{
return false;
}
}
And then you have to register the HttpClient in the DI container like this and it will work perfectly.
services.AddHttpClient("Lynx", client =>
{
client.BaseAddress = new Uri(Configuration.GetSection("LynxUrl").Value);
}).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { Proxy = new MyProxy()});

Categories

Resources