C# System.Net
Network programming and web requests
🌐 What is System.Net?
System.Net provides classes for network communication and web requests. It enables your programs to download data from websites, make API calls, send emails, and communicate over networks using various protocols.
// Simple web request
using System.Net.Http;
HttpClient client = new HttpClient();
string result = await client.GetStringAsync("https://api.example.com");
Core System.Net Features
HttpClient
Make HTTP requests
var client = new HttpClient();
await client.GetStringAsync(url);
WebClient
Download web content
var client = new WebClient();
client.DownloadFile(url, path);
TcpClient
TCP network connections
var client = new TcpClient();
client.Connect(host, port);
SmtpClient
Send emails
var smtp = new SmtpClient();
smtp.Send(mailMessage);
🔹 HttpClient - Making Web Requests
HttpClient is the modern way to make HTTP requests in C#. Use it to call APIs, download web pages, and communicate with web services. It supports GET, POST, PUT, DELETE and other HTTP methods for complete web interaction.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Create HttpClient (reuse for multiple requests)
using HttpClient client = new HttpClient();
try
{
// GET request
string url = "https://jsonplaceholder.typicode.com/posts/1";
string response = await client.GetStringAsync(url);
Console.WriteLine("Response:");
Console.WriteLine(response);
// GET with HttpResponseMessage
HttpResponseMessage result = await client.GetAsync(url);
Console.WriteLine($"\nStatus Code: {result.StatusCode}");
Console.WriteLine($"Success: {result.IsSuccessStatusCode}");
// Read content
string content = await result.Content.ReadAsStringAsync();
Console.WriteLine($"Content Length: {content.Length} characters");
}
catch (HttpRequestException e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
Output:
Response:
{
"userId": 1,
"id": 1,
"title": "Sample Post"
}
Status Code: OK
Success: True
Content Length: 292 characters
🔹 POST Requests with HttpClient
POST requests send data to web servers, commonly used for submitting forms, creating resources, or sending JSON data to APIs. HttpClient makes it easy to send different content types and handle responses.
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using HttpClient client = new HttpClient();
try
{
// Prepare JSON data
string jsonData = @"{
""title"": ""My Post"",
""body"": ""This is the content"",
""userId"": 1
}";
// Create content
StringContent content = new StringContent(
jsonData,
Encoding.UTF8,
"application/json"
);
// POST request
string url = "https://jsonplaceholder.typicode.com/posts";
HttpResponseMessage response = await client.PostAsync(url, content);
Console.WriteLine($"Status: {response.StatusCode}");
// Read response
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine("\nResponse:");
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
Output:
Status: Created
Response:
{
"title": "My Post",
"body": "This is the content",
"userId": 1,
"id": 101
}
🔹 WebClient - Simple Downloads
WebClient provides simple methods for downloading files and web content. While HttpClient is preferred for new code, WebClient is still useful for quick downloads and simple scenarios where you need straightforward file retrieval.
using System;
using System.Net;
class Program
{
static void Main()
{
using WebClient client = new WebClient();
try
{
// Download string
string url = "https://jsonplaceholder.typicode.com/posts/1";
string content = client.DownloadString(url);
Console.WriteLine("Downloaded content:");
Console.WriteLine(content.Substring(0, 100) + "...");
// Download file
string fileUrl = "https://example.com/sample.txt";
string savePath = "downloaded.txt";
// client.DownloadFile(fileUrl, savePath);
// Console.WriteLine($"\nFile saved to: {savePath}");
// Download data as bytes
byte[] data = client.DownloadData(url);
Console.WriteLine($"\nDownloaded {data.Length} bytes");
// Upload string (POST)
string postUrl = "https://jsonplaceholder.typicode.com/posts";
string postData = "title=Test&body=Content";
string response = client.UploadString(postUrl, postData);
Console.WriteLine("\nUpload response received");
}
catch (WebException e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
Output:
Downloaded content:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere..."
Downloaded 292 bytes
Upload response received
🔹 Working with Headers
HTTP headers carry important information about requests and responses. You can add custom headers for authentication, specify content types, set user agents, and read response headers to understand server responses better.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using HttpClient client = new HttpClient();
// Add default headers
client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add authorization header
client.DefaultRequestHeaders.Add("Authorization", "Bearer token123");
Console.WriteLine("Request Headers:");
foreach (var header in client.DefaultRequestHeaders)
{
Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
}
try
{
string url = "https://jsonplaceholder.typicode.com/posts/1";
HttpResponseMessage response = await client.GetAsync(url);
Console.WriteLine("\nResponse Headers:");
foreach (var header in response.Headers)
{
Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
}
Console.WriteLine($"\nContent Type: {response.Content.Headers.ContentType}");
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
Output:
Request Headers:
User-Agent: MyApp/1.0
Accept: application/json
Authorization: Bearer token123
Response Headers:
Date: Mon, 06 Oct 2025 14:30:00 GMT
Server: cloudflare
Content Type: application/json; charset=utf-8
🔹 DNS and IP Addresses
The Dns class helps you work with domain names and IP addresses. You can resolve hostnames to IP addresses, get information about network hosts, and perform reverse DNS lookups for network diagnostics and tools.
using System;
using System.Net;
class Program
{
static void Main()
{
try
{
// Get host name
string hostName = Dns.GetHostName();
Console.WriteLine($"Host Name: {hostName}");
// Get host entry
IPHostEntry hostEntry = Dns.GetHostEntry(hostName);
Console.WriteLine($"\nHost: {hostEntry.HostName}");
// Display IP addresses
Console.WriteLine("\nIP Addresses:");
foreach (IPAddress ip in hostEntry.AddressList)
{
Console.WriteLine($"- {ip} ({ip.AddressFamily})");
}
// Resolve domain name
string domain = "google.com";
IPHostEntry googleEntry = Dns.GetHostEntry(domain);
Console.WriteLine($"\n{domain} IP Addresses:");
foreach (IPAddress ip in googleEntry.AddressList)
{
Console.WriteLine($"- {ip}");
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
Output:
Host Name: DESKTOP-ABC123
Host: DESKTOP-ABC123
IP Addresses:
- 192.168.1.100 (InterNetwork)
- fe80::1234:5678 (InterNetworkV6)
google.com IP Addresses:
- 142.250.185.46
- 2607:f8b0:4004:c07::71
🔹 Error Handling
Error handling in C# is managed using try-catch blocks to gracefully manage unexpected runtime exceptions. The try block contains code that might throw an error, while the catch block captures and handles specific or general exceptions, preventing application crashes. For example, when an HTTP request fails with a 500 Internal Server Error, catch blocks can log the error, display a user-friendly message, or implement retry logic. This ensures robustness and improves user experience by handling failures predictively.
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(5);
string[] urls = {
"https://jsonplaceholder.typicode.com/posts/1",
"https://invalid-url-that-does-not-exist.com",
"https://httpstat.us/500"
};
foreach (string url in urls)
{
try
{
Console.WriteLine($"\nTrying: {url}");
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
Console.WriteLine($"✓ Success: {response.StatusCode}");
}
else
{
Console.WriteLine($"✗ Failed: {response.StatusCode}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"✗ Request Error: {e.Message}");
}
catch (TaskCanceledException)
{
Console.WriteLine("✗ Timeout: Request took too long");
}
catch (Exception e)
{
Console.WriteLine($"✗ Error: {e.Message}");
}
}
}
}
Output:
Trying: https://jsonplaceholder.typicode.com/posts/1
✓ Success: OK
Trying: https://invalid-url-that-does-not-exist.com
✗ Request Error: No such host is known
Trying: https://httpstat.us/500
✗ Failed: InternalServerError