The following code takes a target uri and gets its content as stream. Before the network call is made, it checks whether a proxy is required to access the target uri or not.
This works perfectly for .NET apps in full-framework (i.e. v4.8):
var targetUri = new Uri("...");
HttpClient client;
// get the system default web proxy ...
var proxyUri = WebRequest.DefaultWebProxy.GetProxy(targetUri);
// ... and check whether it should be used or not
var proxyAuthorityEqualsTargetAuthority = proxyUri?.Authority?.Equals(targetUri.Authority) == true;
var proxyRequired = !proxyAuthorityEqualsTargetAuthority;
if (proxyRequired)
{
var proxy = new WebProxy()
{
Address = proxyUri,
BypassProxyOnLocal = false,
UseDefaultCredentials = true
};
var httpClientHandler = new HttpClientHandler { Proxy = proxy };
client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
}
else
{
client = new HttpClient();
}
await client.GetStreamAsync(targetUri) ...
However it does not work within a .NET Core app:
Accessing WebRequest.DefaultWebProxy.GetProxy(targetUri) will throw a PlatformNotSupportedException:
Operation is not supported on this platform.
So I tried this line instead which is supported by .NET Core as well:
// deprecated: var proxyUri = new Uri(WebRequest.DefaultWebProxy.GetProxy(targetUri).AbsoluteUri);
var proxyUri = new WebProxy().GetProxy(targetUri);
However, the returning proxyUri.Authority does always return the targetUri now (both, in .NET and .NET Core) instead of the address to the proxy server like WebRequest.DefaultWebProxy.GetProxy(targetUri) does in .NET.
This way, proxyAuthorityEqualsTargetAuthority is always true and therefore, proxyRequired is always false. Accessing the target uri directly throws a 407 (Proxy Authentication Required).
Does anyone know how to get the address of the default web proxy in .NET Core?
Okay, I don't know what I missed as I tried this weeks ago. I tried again and everything seems fine.
With CredentialCache.DefaultCredentials, this short code works with both: .NET and .NET Core.
var targetUri = new Uri("...");
var handler = new HttpClientHandler();
handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
var client = new HttpClient(handler, disposeHandler: true);
await client.GetStreamAsync(targetUri) ...
Related
I'm new at anglesharp. I tried the proxy change at the documentation but it didnt work.
Now i'm using this, it works well with webclient but it isnt working with AngleSharp.
The code i'm trying is ;
var handler = new HttpClientHandler()
{
Proxy = new WebProxy(String.Format("{0}:{1}", "myProxy", "myPort"), false),
PreAuthenticate = true,
UseDefaultCredentials = false,
};
var config = Configuration.Default.WithJs().WithCookies().WithDefaultLoader().With(handler);
//Create a new context for evaluating webpages with the given config
var context = BrowsingContext.New(config);
var document = await context.OpenAsync("https://api.ipify.org?format=json");
Console.WriteLine(document.DocumentElement.OuterHtml);
I'm not getting any error, proxy is not working thats it. I'm getting my original ip not the proxys.
But with WebClient it works well.
You just add something (handler, i.e., a HttpClientHandler instance) to AngleSharp's configuration - something that will not be used by anything in AngleSharp.
First of all AngleSharp's internal HTTP client is only a default client. For compatibility reasons AngleSharp cannot ship with HttpClient instead if uses HttpWebRequest. This also allows you setting a proxy.
Now if you want to use your code I suggest you use AngleSharp.Io (https://www.nuget.org/packages/AngleSharp.Io or https://github.com/AngleSharp/AngleSharp.Io). It's quite simple and straight forward:
var handler = new HttpClientHandler
{
Proxy = new WebProxy(String.Format("{0}:{1}", "myProxy", "myPort"), false),
PreAuthenticate = true,
UseDefaultCredentials = false,
};
var config = Configuration.Default
.WithRequesters(handler)
.WithDefaultLoader()
.WithJs()
.WithTemporaryCookies()
.WithDefaultLoader();
var context = BrowsingContext.New(config);
var document = await context.OpenAsync("https://api.ipify.org?format=json");
Console.WriteLine(document.DocumentElement.OuterHtml)
Only .WithRequesters(handler) has been added. This adds the requesters from AngleSharp.Io. By providing handler we can configure the HttpClient.
Hope that helps!
I have REST Apis and now I want to call them in asp.net core project.
My project is based on ASP.NET Core V2.
To do this , I wrote these lines of code :
services.AddHttpClient("apiserver")
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler()
{
AllowAutoRedirect = false,
UseDefaultCredentials = true,
Proxy = new WebProxy
{
Address = new Uri("proxyserver:80"),
Credentials = new NetworkCredential("user", "pass", "domain")
}
};
});
using (var client = _httpClientFactory.CreateClient("apiserver"))
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
var result = client.GetAsync("http://url/api/user/test/");
var response = result.Result.Content.ReadAsStringAsync();
return Ok(result.Result.StatusCode);
}
This Code Always Return 404 Error Code(Not Found) but when I enter full adreess (http://url/api/user/test/) in browser it works fine.
And Also I call the REST Address in Postman it works probably and return My expected result.
what is problem whit this?
I am trying to connect to a proxy via this piece of code using HttpClient.
i would like to connect to a proxy strictly using HttpClient, or if unable to. using any c# library as long as the task is achieved.
HttpClientHandler handler = new HttpClientHandler();
//setup web proxy and credentials
var webproxy =
new WebProxy("94.232.55.98", 8080)//ip and port number
{
UseDefaultCredentials = false,
Credentials = CredentialCache.DefaultCredentials
};
handler = new HttpClientHandler
{
Proxy = webproxy,
UseProxy = true,
PreAuthenticate = true,
UseDefaultCredentials = false
};
container = new CookieContainer();
handler.CookieContainer = container;
handler.UseCookies = true;
client = new HttpClient(handler);
//Query a url and get its contents, but the request was not using any proxy seemingly
HttpResponseMessage responseMessage = client.GetAsync("https://shop.shoprite.com/").Result;
Looking at the code i am in need of guidance on how to connect httpclient to a AU proxy, and how to possibly get a proxy with or without credentials and to make it work all together.
I am trying to access a website geo blocked only in Australia that is why im trying to use a proxy.
Thanks in advance!
EDIT:
I have retrieved my proxy from this site ( looking at AU proxies )
https://free-proxy-list.net/ and i get the first ip and put it on WebProxy, having 8080 as port number as an example
but it doesnt seem to work.
When i am about to request the site, i am having an error like this accessing a site that is geo blocked anywhere else except in australia.
It looks like your code is correct, however the host you are trying to connect to is not accessible through the proxy you are trying to use. You can get a more useful error message by altering the last few lines to utilise the EnsureSuccessStatusCode method. This will throw an exception if the status code is not 2XX.
using (var client = new HttpClient(handler))
using (var responseMessage = await client.GetAsync("http://shop.shoprite.com/"))
{
responseMessage.EnsureSuccessStatusCode();
responseMessage.Dump();
}
I use a third-party server written in Java.
WSDL is taken with the style of rpc/literal.
Connection to the service is initialized as follows:
private static MLPortChannel GetMerlionClient()
{
BasicHttpsBinding binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.MaxReceivedMessageSize = 4096000;
EndpointAddress adress = new EndpointAddress(new Uri(#"https://apitest.merlion.com/rl/mlservice3"));
ChannelFactory<MLPortChannel> factory = new ChannelFactory<MLPortChannel>(binding, adress);
factory.Credentials.UserName.UserName = mlLogin;
factory.Credentials.UserName.Password = mlPassword;
return factory.CreateChannel();
}
It is works correctly only for one method and returns the correct data type and the data.
When I call other methods, they returns error as:
"Can not convert an object of type " ... MLService3RLTest.CatalogResult [] " of the type " ... MLService3RLTest.ShipmentDatesResult []"
In this example return type must be ShipmentDatesResult[].
I tested the service via special tool. All requests and responses is correct and returned correct XML.
What may be the cause of this error? Perhaps something needs to be configured for SOAP service. Maybe some magic option with right value?
If, instead of referring to the service, make a web link which uses the technology of web services .Net FrameWork 2.0 what works
var client = new WpfApplication1.com.merlion.apitest.MLService();
var myCredentials = new System.Net.NetworkCredential(Логин, Пароль);
// Create a webrequest with the specified URL.
var url = "https://apitest.merlion.com/rl/mlservice3";;
client.Credentials = myCredentials.GetCredential(new Uri(url), "Basic");
textBox.AppendText(client.helloWorld("Привет"));
var ответ = client.getCatalog("N1");
var массив = new string[] { "" };
var rz = client.getItems("N10100", массив, "", 0, 2, "");
add
client.PreAuthenticate = true;
I want to test my Web API service using in-memory HttpServer.
The current setup looks the following:
var httpConfig = CreateTestHttpConfiguration();
var server = new HttpServer(httpConfig);
var handler = new WebRequestHandler();
var cert = new X509Certificate2("filename", "password");
handler.ClientCertificates.Add(cert);
var client = HttpClientFactory.Create(handler, server);
I can make requests to the server using these client and everything works except that certificate is not added to the request.
As I understand that happens since server executes before handler (I can't rearrange them since they implement different interfaces) and since server immediately responses handler is not even executed (I've tested this assumption using HttpClientHandler subclass instead of handler).
So my question is: How can I add the client certificate for in-memory testing?
This approach will do it:
var server = new HttpServer(configuration);
var invoker = new HttpMessageInvoker(server);
var certificate = GetCertificate();
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/YourPath");
request.Properties[HttpPropertyKeys.ClientCertificateKey] = certificate;
var result = await invoker.SendAsync(request, CancellationToken.None);