The HttpClient
class in C# provides a powerful way to send HTTP requests and handle responses. Here's a comprehensive guide on sending PUT requests using HttpClient
.
Basic PUT Request with JSON Data
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class Program
{
static async Task Main(string[] args)
{
var url = "https://api.example.com/users/123";
var userData = new
{
Name = "John Doe",
Email = "john.doe@example.com",
Age = 30
};
var jsonContent = JsonSerializer.Serialize(userData);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
using var client = new HttpClient();
try
{
var response = await client.PutAsync(url, content);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Success: {responseBody}");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Request error: {ex.Message}");
}
}
}
PUT Request with Custom Headers
using var client = new HttpClient();
// Add custom headers
client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
client.DefaultRequestHeaders.Add("Authorization", "Bearer your-token-here");
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = await client.PutAsync(url, content);
PUT Request with Form Data
var formData = new List<KeyValuePair<string, string>>
{
new("name", "John Doe"),
new("email", "john@example.com"),
new("age", "30")
};
var content = new FormUrlEncodedContent(formData);
var response = await client.PutAsync(url, content);
PUT Request with File Upload
using var content = new MultipartFormDataContent();
// Add text fields
content.Add(new StringContent("John Doe"), "name");
content.Add(new StringContent("john@example.com"), "email");
// Add file
var fileContent = new ByteArrayContent(File.ReadAllBytes("profile.jpg"));
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(fileContent, "avatar", "profile.jpg");
var response = await client.PutAsync(url, content);
Best Practices with IHttpClientFactory
For production applications, use IHttpClientFactory
to avoid socket exhaustion:
// In Startup.cs or Program.cs
services.AddHttpClient();
// In your service class
public class ApiService
{
private readonly HttpClient _httpClient;
public ApiService(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient();
}
public async Task<bool> UpdateUserAsync(int userId, object userData)
{
var url = $"https://api.example.com/users/{userId}";
var jsonContent = JsonSerializer.Serialize(userData);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
try
{
var response = await _httpClient.PutAsync(url, content);
return response.IsSuccessStatusCode;
}
catch (HttpRequestException)
{
return false;
}
}
}
Error Handling and Status Code Checking
var response = await client.PutAsync(url, content);
switch (response.StatusCode)
{
case HttpStatusCode.OK:
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Updated successfully: {result}");
break;
case HttpStatusCode.NotFound:
Console.WriteLine("Resource not found");
break;
case HttpStatusCode.Unauthorized:
Console.WriteLine("Authentication required");
break;
case HttpStatusCode.BadRequest:
var error = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Bad request: {error}");
break;
default:
Console.WriteLine($"Request failed with status: {response.StatusCode}");
break;
}
Key Points to Remember
- Use
System.Text.Json
: For .NET Core 3.0+, preferSystem.Text.Json
over Newtonsoft.Json for better performance - Proper Disposal: Always dispose of
HttpClient
usingusing
statements or dependency injection - Content-Type: Set the correct content type header (e.g.,
application/json
,application/x-www-form-urlencoded
) - Error Handling: Always handle potential exceptions and check response status codes
- Authentication: Add authorization headers when required by the API
- Reuse HttpClient: Use
IHttpClientFactory
in production to avoid socket exhaustion
The PUT method is idempotent, meaning multiple identical requests should have the same effect as a single request. Use PUT when you want to update or replace an entire resource at a specific URL.