.NET MAUI Networking

Build cross-platform apps with native UIs and .NET

MAUI Networking

This document provides a comprehensive guide to implementing networking features in your .NET MAUI applications. Learn how to make HTTP requests, consume web services, handle real-time communication with WebSockets, and monitor network connectivity.

Note: Ensure you have the necessary platform permissions configured in your project's manifest files for network access. For Android, this is typically android.permission.INTERNET.

Using HttpClient

The HttpClient class is the primary mechanism for making HTTP requests in .NET. It's recommended to use a single instance of HttpClient throughout your application's lifetime for better performance and resource management.

Here's a basic example of making a GET request:


using System;
using System.Net.Http;
using System.Threading.Tasks;

public class NetworkService
{
    private static readonly HttpClient client = new HttpClient();

    public async Task<string> GetDataAsync(string url)
    {
        try
        {
            HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode(); // Throws an exception if the status code is not a success code
            string responseBody = await response.Content.ReadAsStringAsync();
            return responseBody;
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine($"Request error: {e.Message}");
            return null;
        }
    }
}
            

Consuming RESTful Services

MAUI applications can easily consume RESTful APIs. You can use HttpClient to send requests (GET, POST, PUT, DELETE) and deserialize the JSON or XML responses into .NET objects.

For JSON serialization and deserialization, use the System.Text.Json namespace (recommended) or Newtonsoft.Json.


using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

// Define your model classes to match the API response
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class ProductService
{
    private static readonly HttpClient client = new HttpClient();

    public ProductService()
    {
        client.BaseAddress = new Uri("https://api.example.com/"); // Replace with your API base URL
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<Product> GetProductAsync(int id)
    {
        string url = $"products/{id}";
        HttpResponseMessage response = await client.GetAsync(url);
        if (response.IsSuccessStatusCode)
        {
            var json = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<Product>(json);
        }
        return null;
    }

    public async Task<bool> CreateProductAsync(Product product)
    {
        var json = JsonSerializer.Serialize(product);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        HttpResponseMessage response = await client.PostAsync("products", content);
        return response.IsSuccessStatusCode;
    }
}
            

Using WebSockets

WebSockets provide a full-duplex communication channel over a single TCP connection, enabling real-time, bi-directional data transfer between client and server.

MAUI supports WebSockets through the System.Net.WebSockets namespace.


using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

public class WebSocketClient : IDisposable
{
    private ClientWebSocket _webSocket;
    private Uri _uri;
    private CancellationTokenSource _cancellationTokenSource;

    public WebSocketClient(Uri uri)
    {
        _uri = uri;
        _webSocket = new ClientWebSocket();
        _cancellationTokenSource = new CancellationTokenSource();
    }

    public async Task ConnectAsync()
    {
        await _webSocket.ConnectAsync(_uri, _cancellationTokenSource.Token);
        Console.WriteLine($"WebSocket connected: {_webSocket.State}");
        _ = ReceiveMessagesAsync(); // Start receiving messages in the background
    }

    public async Task SendMessageAsync(string message)
    {
        if (_webSocket.State == WebSocketState.Open)
        {
            var buffer = Encoding.UTF8.GetBytes(message);
            await _webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, _cancellationTokenSource.Token);
            Console.WriteLine($"Sent: {message}");
        }
    }

    private async Task ReceiveMessagesAsync()
    {
        var buffer = new byte[1024];
        try
        {
            while (_webSocket.State == WebSocketState.Open)
            {
                var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cancellationTokenSource.Token);
                if (result.MessageType == WebSocketMessageType.Text)
                {
                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    Console.WriteLine($"Received: {message}");
                    // TODO: Process received message
                }
                else if (result.MessageType == WebSocketMessageType.Close)
                {
                    await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client disconnecting", _cancellationTokenSource.Token);
                    Console.WriteLine($"WebSocket closed: {_webSocket.State}");
                    break;
                }
            }
        }
        catch (WebSocketException ex)
        {
            Console.WriteLine($"WebSocket error: {ex.Message}");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Receive operation canceled.");
        }
    }

    public void Dispose()
    {
        _cancellationTokenSource?.Cancel();
        _cancellationTokenSource?.Dispose();
        _webSocket?.Dispose();
    }
}
            

Checking Network Connectivity

It's crucial to check for network availability before attempting network operations to provide a better user experience and prevent errors.

MAUI provides the