Networking in .NET MAUI
.NET MAUI (Multi-platform App UI) provides robust support for network operations, allowing your applications to communicate with web services, transfer data, and interact with online resources. This document explores the various networking capabilities available within .NET MAUI, leveraging the power of the .NET platform.
HttpClient
The HttpClient
class, part of the System.Net.Http
namespace, is the primary mechanism for making HTTP requests. It supports various HTTP methods (GET, POST, PUT, DELETE, etc.) and allows you to send and receive data in different formats, such as JSON or XML.
Making a GET Request
Here's a simple example of fetching data from a public API using HttpClient
:
using System.Net.Http;
using System.Threading.Tasks;
public class DataService
{
private readonly HttpClient _httpClient = new HttpClient();
public async Task<string> GetDataAsync(string url)
{
try
{
HttpResponseMessage response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode(); // Throw if HTTP status is not success
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
catch (HttpRequestException e)
{
// Handle exceptions (e.g., network errors, invalid URL)
Console.WriteLine($"Request error: {e.Message}");
return null;
}
}
}
WebSockets
For real-time, bi-directional communication, .NET MAUI supports WebSockets. This is ideal for scenarios like chat applications, live notifications, or collaborative editing. The System.Net.WebSockets
namespace provides the necessary classes.
Establishing a WebSocket Connection
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
public class WebSocketClient
{
private ClientWebSocket _webSocket = new ClientWebSocket();
public async Task ConnectAsync(string uri)
{
await _webSocket.ConnectAsync(new Uri(uri), CancellationToken.None);
// Start a loop to receive messages
_ = ReceiveMessagesAsync();
}
private async Task ReceiveMessagesAsync()
{
var buffer = new byte[1024 * 4];
while (_webSocket.State == WebSocketState.Open)
{
var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text)
{
string message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine($"Received: {message}");
}
}
}
public async Task SendMessageAsync(string message)
{
if (_webSocket.State == WebSocketState.Open)
{
var buffer = System.Text.Encoding.UTF8.GetBytes(message);
await _webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
}
}
public async Task DisconnectAsync()
{
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client Disconnected", CancellationToken.None);
}
}
Consuming RESTful Services
Most modern web APIs are built using REST principles. .NET MAUI applications can easily consume these services by leveraging HttpClient
and JSON serialization/deserialization libraries like System.Text.Json
or Newtonsoft.Json.
Deserializing JSON Responses
Assume you have a C# class representing the data you expect:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
And here's how to deserialize the response:
using System.Text.Json;
// ... inside DataService class ...
public async Task<User> GetUserAsync(string url)
{
string json = await GetDataAsync(url);
if (json != null)
{
return JsonSerializer.Deserialize<User>(json);
}
return null;
}
Network Access Detector
It's crucial to check for network connectivity before attempting network operations. .NET MAUI provides the Connectivity
API to detect the network access type (Wi-Fi, Cellular, None).
Checking Network Connectivity
using Microsoft.Maui.Networking;
public void CheckNetworkStatus()
{
var connectivity = Connectivity.Current;
var accessType = connectivity.NetworkAccess;
if (accessType == NetworkAccess.Internet)
{
Console.WriteLine("Internet access is available.");
// Proceed with network operations
}
else if (accessType == NetworkAccess.ConstrainedInternet)
{
Console.WriteLine("Constrained internet access is available.");
}
else if (accessType == NetworkAccess.Local)
{
Console.WriteLine("Local network access is available.");
}
else
{
Console.WriteLine("No internet access.");
// Inform user or disable network-dependent features
}
}
You can also subscribe to network change events:
public void SubscribeToNetworkChanges()
{
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
}
private void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e)
{
var accessType = e.NetworkAccess;
if (accessType == NetworkAccess.Internet)
{
Console.WriteLine("Network became available.");
}
else
{
Console.WriteLine("Network became unavailable.");
}
}
Platform-Specific Networking
While .NET MAUI aims for cross-platform consistency, there might be scenarios where you need to access platform-specific networking features. You can achieve this using conditional compilation or dependency injection of platform-specific implementations.
For example, on Android, you might need to handle network permissions explicitly in the manifest. On iOS, you might interact with NSURLSession
or other native APIs.
Using Conditional Compilation
#if ANDROID
// Android-specific networking code
// e.g., accessing network state service
#elif IOS
// iOS-specific networking code
// e.g., using NSUrlSession
#endif
Refer to the platform-specific documentation for advanced networking features.