Sie sind auf Seite 1von 4

Chapter 16 - Networking

Client-Side Classes
WebClient Download Page

WebClient wc = new WebClient { Proxy = null };


wc.DownloadFile ("http://www.albahari.com/nutshell/code.aspx", "code.htm");

OpenHtml ("code.htm");

void OpenHtml (string location)


{
if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows))
Process.Start (new ProcessStartInfo ("cmd", $"/c start {location}"));
else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux))
Process.Start ("xdg-open", location); // Desktop Linux
else throw new Exception ("Platform-specific code needed to open URL.");
}

WebRequest and WebResponse

void DownloadPage()
{
WebRequest req = WebRequest.Create
("http://www.albahari.com/nutshell/code.html");
req.Proxy = null;
using (WebResponse res = req.GetResponse())
using (Stream rs = res.GetResponseStream())
using (FileStream fs = File.Create ("code_sync.html"))
rs.CopyTo (fs);
}

async Task DownloadPageAsync()


{
WebRequest req = WebRequest.Create
("http://www.albahari.com/nutshell/code.html");
req.Proxy = null;
using (WebResponse res = await req.GetResponseAsync())
using (Stream rs = res.GetResponseStream())
using (FileStream fs = File.Create ("code_async.html"))
await rs.CopyToAsync (fs);
}

DownloadPage();
await DownloadPageAsync();

foreach (var file in Directory.EnumerateFiles (".", "*.html"))


Console.WriteLine ($"{file} {new FileInfo (file).Length} bytes");

HttpClient - simple request

string html = await new HttpClient().GetStringAsync ("http://linqpad.net");


html.Dump();

HttpClient - parallel downloads

var client = new HttpClient();


var task1 = client.GetStringAsync ("http://www.linqpad.net");
var task2 = client.GetStringAsync ("http://www.albahari.com");

(await task1).Length.Dump ("First page length");


(await task2).Length.Dump ("Second page length");

HttpClient - response messages

var client = new HttpClient();


// The GetAsync method also accepts a CancellationToken.
HttpResponseMessage response = await client.GetAsync ("http://www.linqpad.net");
response.EnsureSuccessStatusCode();
string html = await response.Content.ReadAsStringAsync();

HttpClient - uploading data

var client = new HttpClient (new HttpClientHandler { UseProxy = false });


var request = new HttpRequestMessage (
HttpMethod.Post, "http://www.albahari.com/EchoPost.aspx");
request.Content = new StringContent ("This is a test");
HttpResponseMessage response = await client.SendAsync (request);
response.EnsureSuccessStatusCode();
Console.WriteLine (await response.Content.ReadAsStringAsync());

HttpClient - Using HttpMessageHandler for mocking

async Task Main()


{
var mocker = new MockHandler (request =>
new HttpResponseMessage (HttpStatusCode.OK)
{
Content = new StringContent ("You asked for " + request.RequestUri)
});
var client = new HttpClient (mocker);
var response = await client.GetAsync ("http://www.linqpad.net");
string result = await response.Content.ReadAsStringAsync();

Assert.AreEqual ("You asked for http://www.linqpad.net/", result);


}

class MockHandler : HttpMessageHandler


{
Func<HttpRequestMessage, HttpResponseMessage> _responseGenerator;

public MockHandler
(Func<HttpRequestMessage, HttpResponseMessage> responseGenerator)
{
_responseGenerator = responseGenerator;
}

protected override Task<HttpResponseMessage> SendAsync


(HttpRequestMessage request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var response = _responseGenerator (request);
response.RequestMessage = request;
return Task.FromResult (response);
}
}

static class Assert


{
public static void AreEqual (object o1, object o2)
{
if (!Equals (o1, o2)) throw new Exception ("Objects are not equal");
}
}

HttpClient - Chaining handlers with DelegatingHandler

async Task Main()


{
var mocker = new MockHandler (request =>
new HttpResponseMessage (HttpStatusCode.OK)
{
Content = new StringContent ("You asked for " + request.RequestUri)
});

var logger = new LoggingHandler (mocker);

var client = new HttpClient (logger);


var response = await client.GetAsync ("http://www.linqpad.net");
string result = await response.Content.ReadAsStringAsync();

Assert.AreEqual ("You asked for http://www.linqpad.net/", result);


}

class MockHandler : HttpMessageHandler


{
Func<HttpRequestMessage, HttpResponseMessage> _responseGenerator;

public MockHandler
(Func<HttpRequestMessage, HttpResponseMessage> responseGenerator)
{
_responseGenerator = responseGenerator;
}

protected override Task<HttpResponseMessage> SendAsync


(HttpRequestMessage request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var response = _responseGenerator (request);
response.RequestMessage = request;
return Task.FromResult (response);
}
}

class LoggingHandler : DelegatingHandler


{
public LoggingHandler (HttpMessageHandler nextHandler)
{
InnerHandler = nextHandler;
}

protected async override Task<HttpResponseMessage> SendAsync


(HttpRequestMessage request, CancellationToken cancellationToken)
{
Console.WriteLine ("Requesting: " + request.RequestUri);
var response = await base.SendAsync (request, cancellationToken);
Console.WriteLine ("Got response: " + response.StatusCode);
return response;
}
}

static class Assert


{
public static void AreEqual (object o1, object o2)
{
if (!Equals (o1, o2)) throw new Exception ("Objects are not equal");
}
}

EXTRA - HttpClient With Progress

async Task Main()


{
var linqPadProgressBar = new Util.ProgressBar ("Download progress").Dump();

var progress = new Progress<double>();

progress.ProgressChanged += (sender, value) =>


linqPadProgressBar.Percent = (int) value;

var cancellationToken = new CancellationTokenSource();

using var destination = File.OpenWrite ("LINQPad6Setup.exe");


await DownloadFileAsync ("https://www.linqpad.net/GetFile.aspx?LINQPad6Setup.exe", destination, progress, default);
}

// Based on: https://stackoverflow.com/q/21169573/141172


// https://stackoverflow.com/q/230128/141172

HttpClient client = new HttpClient();

async Task CopyStreamWithProgressAsync (Stream input, Stream output, long total, IProgress<double> progress, CancellationToken t
{
const int IO_BUFFER_SIZE = 8 * 1024; // Optimal size depends on your scenario

// Expected size of input stream may be known from an HTTP header when reading from HTTP. Other streams may have their
// own protocol for pre-reporting expected size.

var canReportProgress = total != -1 && progress != null;


var totalRead = 0L;
byte[] buffer = new byte [IO_BUFFER_SIZE];
int read;

while ((read = await input.ReadAsync (buffer, 0, buffer.Length)) > 0)


{
token.ThrowIfCancellationRequested();
await output.WriteAsync (buffer, 0, read);
totalRead += read;
if (canReportProgress)
progress.Report ((totalRead * 1d) / (total * 1d) * 100);
}
}

async Task DownloadFileAsync (string url, Stream destination, IProgress<double> progress, CancellationToken token)
{
var response = await client.GetAsync (url, HttpCompletionOption.ResponseHeadersRead, token);

if (!response.IsSuccessStatusCode)
throw new Exception (string.Format ("The request returned with HTTP status code {0}", response.StatusCode));

var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;

using var source = await response.Content.ReadAsStreamAsync();

await CopyStreamWithProgressAsync(source, destination, total, progress, token);


}

Exception handling

WebClient wc = new WebClient { Proxy = null };


try
{
string s = wc.DownloadString ("http://www.albahari.com/notthere");
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.NameResolutionFailure)
Console.WriteLine ("Bad domain name");
else if (ex.Status == WebExceptionStatus.ProtocolError)
{
HttpWebResponse response = (HttpWebResponse)ex.Response;
Console.WriteLine (response.StatusDescription); // "Not Found"
if (response.StatusCode == HttpStatusCode.NotFound)
Console.WriteLine ("Not there!"); // "Not there!"
}
else throw;
}

IP Addresses and URIs


Working with HTTP
C# 8.0
in a Nutshell
About the Book
 

Code Listings
C# 8.0 in a Nutshell
C# 7.0 in a Nutshell
C# 6.0 in a Nutshell

Extras
 

Contact Authors
 

Buy print or Kindle edition

Buy PDF edition

Read via Safari subscription

Das könnte Ihnen auch gefallen