diff --git a/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/program.cs b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/program.cs new file mode 100644 index 00000000000..2ba4f7cc103 --- /dev/null +++ b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/program.cs @@ -0,0 +1,59 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; + +class HttpClientHandler_SecureExample +{ + // + static async Task Main() + { + // Create an HttpClientHandler object and set to use default credentials + HttpClientHandler handler = new HttpClientHandler(); + + // Set custom server validation callback + handler.ServerCertificateCustomValidationCallback = ServerCertificateCustomValidation; + + // Create an HttpClient object + HttpClient client = new HttpClient(handler); + + // Call asynchronous network methods in a try/catch block to handle exceptions + try + { + HttpResponseMessage response = await client.GetAsync("https://docs.microsoft.com/"); + + response.EnsureSuccessStatusCode(); + + string responseBody = await response.Content.ReadAsStringAsync(); + Console.WriteLine($"Read {responseBody.Length} characters"); + } + catch (HttpRequestException e) + { + Console.WriteLine("\nException Caught!"); + Console.WriteLine($"Message: {e.Message} "); + } + + // Need to call dispose on the HttpClient and HttpClientHandler objects + // when done using them, so the app doesn't leak resources + handler.Dispose(); + client.Dispose(); + } + + private static bool ServerCertificateCustomValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslErrors) + { + // It is possible inpect the certificate provided by server + Console.WriteLine($"Requested URI: {requestMessage.RequestUri}"); + Console.WriteLine($"Effective date: {certificate.GetEffectiveDateString()}"); + Console.WriteLine($"Exp date: {certificate.GetExpirationDateString()}"); + Console.WriteLine($"Issuer: {certificate.Issuer}"); + Console.WriteLine($"Subject: {certificate.Subject}"); + + // Based on the custom logic it is possible to decide whether the client considers certificate valid or not + Console.WriteLine($"Errors: {sslErrors}"); + return sslErrors == SslPolicyErrors.None; + } + // +} diff --git a/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/system.net.http.httpclienthandler-secure.csproj b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/system.net.http.httpclienthandler-secure.csproj new file mode 100644 index 00000000000..cc844fe1c30 --- /dev/null +++ b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/system.net.http.httpclienthandler-secure.csproj @@ -0,0 +1,9 @@ + + + + Exe + net5.0 + dotnet_api_docs + + + diff --git a/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/source.cs b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/source.cs index 61defd9e9d6..5167758fbf3 100644 --- a/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/source.cs +++ b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/source.cs @@ -2,6 +2,7 @@ using System.IO; using System.Net; using System.Net.Http; +using System.Threading.Tasks; class HttpClientHandler_Example { @@ -16,7 +17,7 @@ static async Task Main() HttpClient client = new HttpClient(handler); // Call asynchronous network methods in a try/catch block to handle exceptions - try + try { HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/"); @@ -27,14 +28,14 @@ static async Task Main() } catch(HttpRequestException e) { - Console.WriteLine("\nException Caught!"); + Console.WriteLine("\nException Caught!"); Console.WriteLine("Message :{0} ",e.Message); } // Need to call dispose on the HttpClient and HttpClientHandler objects // when done using them, so the app doesn't leak resources - handler.Dispose(true); - client.Dispose(true); + handler.Dispose(); + client.Dispose(); } -// +// } diff --git a/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/system.net.http.httpclienthandler.csproj b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/system.net.http.httpclienthandler.csproj new file mode 100644 index 00000000000..cc844fe1c30 --- /dev/null +++ b/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler/cs/system.net.http.httpclienthandler.csproj @@ -0,0 +1,9 @@ + + + + Exe + net5.0 + dotnet_api_docs + + + diff --git a/xml/System.Net.Http/HttpClientHandler.xml b/xml/System.Net.Http/HttpClientHandler.xml index 1302963365f..c3542e8d45f 100644 --- a/xml/System.Net.Http/HttpClientHandler.xml +++ b/xml/System.Net.Http/HttpClientHandler.xml @@ -893,7 +893,19 @@ handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousA Gets or sets a callback method to validate the server certificate. A callback method to validate the server certificate. - To be added. + + can be used to obtain and validate the server certificate. + +## Examples + The following code example displays the server certificate. + + [!code-csharp[System.Net.Http.HttpClientHandler#5](~/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclienthandler-secure/cs/program.cs#1)] + + ]]> + diff --git a/xml/System.Net/ServicePoint.xml b/xml/System.Net/ServicePoint.xml index d65ec58b28c..6282ff9fe96 100644 --- a/xml/System.Net/ServicePoint.xml +++ b/xml/System.Net/ServicePoint.xml @@ -54,7 +54,8 @@ > [!NOTE] > In high load conditions, some applications may run out of free threads in the ThreadPool, which may lead to poor system performance (such as high and variable transaction times). - +> [!IMPORTANT] +> We don't recommend that you use the `ServicePoint` class for new development. Instead, use the class. ## Examples The following code example creates a object that connects to the URI `www.contoso.com`. @@ -204,7 +205,9 @@ ## Remarks Although a object can make multiple connections to an Internet resource, it can maintain only one certificate. - +> [!NOTE] +> Starting in .NET Core 1.0 and later including .NET 5.0 and later, the property always returns null. The is the recomendded way to access the server certificate. + ## Examples The following code example displays the value of this property. diff --git a/xml/System.Net/ServicePointManager.xml b/xml/System.Net/ServicePointManager.xml index 6954f55e90d..26f2b5acd6f 100644 --- a/xml/System.Net/ServicePointManager.xml +++ b/xml/System.Net/ServicePointManager.xml @@ -46,7 +46,8 @@ Developers may want to opt out of this behavior in order to maintain interoperability with their existing SSL3 services or TLS w/ RC4 services. [This article](https://support.microsoft.com/kb/3069494) explains how to modify your code so that the new behavior is disabled. - +> [!IMPORTANT] +> We don't recommend that you use the `ServicePointManager` class for new development. Instead, use the class. ## Examples The following code example creates a object for connections to the URI `www.contoso.com`.