Introduction to API Integration
Consuming data from external APIs is a fundamental aspect of modern web development. ASP.NET Core provides robust tools and libraries to make this process seamless and efficient. This section demonstrates a basic example of how to integrate with a simple RESTful API.
We'll focus on using HttpClient
, the recommended way to make HTTP requests in .NET.
Basic API Example
This example simulates fetching data from a hypothetical "Product API".
C# Code (Controller/Razor Page)
Here's how you might set up a service and use HttpClient
in your ASP.NET Core application:
// In a service class, e.g., ProductService.cs
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
public class ProductService
{
private readonly HttpClient _httpClient;
public ProductService(HttpClient httpClient)
{
// HttpClient is intended to be instantiated once
// per application, rather than per-use.
// It's recommended to use IHttpClientFactory for managing HttpClient instances.
_httpClient = httpClient;
_httpClient.BaseAddress = new Uri("https://api.example.com/v1/"); // Example base URL
}
public async Task<Product> GetProductByIdAsync(int id)
{
try
{
var response = await _httpClient.GetAsync($"products/{id}");
response.EnsureSuccessStatusCode(); // Throws if status code is not 2xx
return await response.Content.ReadFromJsonAsync<Product>();
}
catch (HttpRequestException e)
{
// Log the exception or handle it appropriately
Console.WriteLine($"Request error: {e.Message}");
return null;
}
}
}
// Simple Product Model
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}
// In your Razor Page Model (e.g., Index.cshtml.cs)
public class IndexModel : PageModel
{
private readonly ProductService _productService;
public Product CurrentProduct { get; private set; }
public IndexModel(ProductService productService)
{
_productService = productService;
}
public async Task OnGetAsync(int? productId)
{
// Default to fetching product 1 if no ID is provided
int idToFetch = productId ?? 1;
CurrentProduct = await _productService.GetProductByIdAsync(idToFetch);
}
}
Razor Page (Index.cshtml)
Displaying the fetched product data:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Product Details</title>
<!-- Link to your site's CSS -->
</head>
<body>
<h1>Product Information</h1>
&comm;-- Product Card -->
&comm;@if (Model.CurrentProduct != null)
{
<div class="product-display-card">
<h2>@Model.CurrentProduct.Name</h2>
<p><strong>ID:</strong> @Model.CurrentProduct.Id</p>
<p><strong>Price:</strong> @Model.CurrentProduct.Price.ToString("C")</p>
<p><strong>Description:</strong> @Model.CurrentProduct.Description</p>
</div>
}
&comm;else
{
<p>Could not load product details. Please try again later.</p>
}
&comm;-- Basic navigation to try other products -->
<nav>
<h3>Try other products:</h3>
<ul>
<li><a href="/?productId=1">Product 1</a></li>
<li><a href="/?productId=2">Product 2</a></li>
<li><a href="/?productId=3">Product 3</a></li>
</ul>
</nav>
</body>
</html>
Note: For actual implementation, ensure you've configured HttpClient
using IHttpClientFactory
in your Startup.cs
or Program.cs
for best practices regarding connection pooling and lifetime management.
Key Considerations
- HttpClient Lifetime: Always use
IHttpClientFactory
to manageHttpClient
instances. Creating a newHttpClient
for every request can lead to socket exhaustion. - Error Handling: Implement robust error handling for network issues, non-success status codes, and deserialization failures.
- Asynchronous Operations: Use
async
andawait
for all I/O-bound operations to keep your application responsive. - Data Serialization: Utilize
System.Net.Http.Json
for easy JSON serialization and deserialization. - Configuration: Externalize API base URLs and other configurations using
appsettings.json
.
Example API Endpoints
Get Product Details
Retrieves detailed information for a specific product by its ID.
List All Products
Fetches a list of all available products.
Search Products
Searches for products based on a keyword in their name or description.