Md Mominul Islam | Software and Data Enginnering | SQL Server, .NET, Power BI, Azure Blog

while(!(succeed=try()));

LinkedIn Portfolio Banner

Latest

Home Top Ad

Responsive Ads Here

Post Top Ad

Responsive Ads Here

Wednesday, September 3, 2025

Azure Integration with ASP.NET Core for Scalable Apps

 

Introduction

In today’s fast-paced digital world, building scalable, cloud-native applications is crucial for businesses to handle growing user demands while ensuring performance, security, and cost-efficiency. Microsoft Azure, paired with ASP.NET Core, provides a robust platform for creating such applications. This comprehensive tutorial will guide you through integrating Azure services like App Service, SQL Database, Blob Storage, and more into your ASP.NET Core applications. From basic setups to advanced architectures, we’ll cover real-world scenarios, best practices, pros and cons, alternatives, and provide plenty of code examples to make the journey engaging and practical.

Whether you’re a beginner dipping your toes into cloud development or an advanced developer aiming to optimize large-scale systems, this guide is designed to be accessible, interactive, and packed with actionable insights. Let’s dive in and build a scalable, cloud-native ASP.NET Core app that powers a photo-sharing platform as our real-world example.


Module 1: Setting Up Your ASP.NET Core App for Azure

Overview

Before integrating Azure services, you need a solid ASP.NET Core application. We’ll create a photo-sharing app where users can upload, store, and view images, leveraging Azure for scalability.

Prerequisites

  • Visual Studio 2022 (or VS Code with .NET CLI)

  • .NET 8.0 SDK

  • Azure account (Sign up for a free trial at azure.microsoft.com)

  • Azure CLI or Azure Developer CLI (optional for deployment)

  • Basic knowledge of C# and ASP.NET Core

Step 1: Create an ASP.NET Core MVC App

Let’s start by creating a new ASP.NET Core MVC project.

  1. Open Visual Studio and select Create a new project.

  2. Choose ASP.NET Core Web App (Model-View-Controller) and name it PhotoSharingApp.

  3. Select .NET 8.0 (Long Term Support) and set Authentication to None for simplicity.

  4. Run the app locally to ensure it works (Ctrl+F5).

Code Example: Basic Program.cs setup

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Step 2: Prepare for Azure Deployment

To deploy to Azure, ensure your app is ready:

  • Use appsettings.json for configuration (e.g., connection strings).

  • Enable dependency injection for Azure services.

  • Test locally before deploying.

Best Practices:

  • Store sensitive data (e.g., connection strings) in Azure Key Vault instead of appsettings.json.

  • Use environment variables for different environments (Development, Staging, Production).

Pros:

  • ASP.NET Core is lightweight, cross-platform, and integrates seamlessly with Azure.

  • Built-in dependency injection simplifies service configuration.

Cons:

  • Initial setup can be complex for beginners.

  • Requires understanding of Azure’s ecosystem for optimal use.

Alternatives:

  • Node.js with Express: Lightweight but lacks ASP.NET Core’s robust typing and middleware.

  • Spring Boot: Java-based, good for enterprise but heavier than ASP.NET Core.


Module 2: Deploying to Azure App Service

Overview

Azure App Service is a fully managed platform for hosting web apps, offering auto-scaling, CI/CD integration, and support for .NET Core. We’ll deploy our photo-sharing app to App Service.

Step 1: Create an App Service in Azure

  1. Log in to the Azure Portal.

  2. Click Create a resource > Web App.

  3. Configure:

    • Subscription: Select your subscription.

    • Resource Group: Create a new one (e.g., PhotoSharingRG).

    • Name: Choose a unique name (e.g., PhotoSharingApp123).

    • Publish: Code.

    • Runtime stack: .NET 8 (LTS).

    • Operating System: Linux (cost-effective).

    • Region: Choose a region close to your users.

    • App Service Plan: Select B1 (Basic) for testing.

  4. Click Review + create, then Create.

Step 2: Deploy from Visual Studio

  1. In Visual Studio, right-click the PhotoSharingApp project and select Publish.

  2. Choose Azure > Azure App Service (Linux).

  3. Select the App Service you created.

  4. Click Publish. Visual Studio will deploy the app, and the URL (e.g., https://photosharingapp123.azurewebsites.net) will open in your browser.

Code Example: Configuring CI/CD with GitHub Actions

  1. Fork the sample repo: Azure-Samples/quickstart-deploy-aspnet-core-app-service.

  2. In your GitHub repo, navigate to Actions and enable workflows.

  3. The default workflow (azure-webapps-dotnet-core.yml) handles build and deploy:

name: Build and deploy ASP.NET Core app to Azure Web App

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '8.0.x'
      - name: Build with dotnet
        run: dotnet build --configuration Release
      - name: Publish
        run: dotnet publish -c Release -o ./publish
      - name: Deploy to Azure Web App
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'PhotoSharingApp123'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}

Best Practices:

  • Use Azure DevOps or GitHub Actions for CI/CD to automate deployments.

  • Enable diagnostic logging in App Service for troubleshooting.

  • Use slots for staging and production to minimize downtime.

Pros:

  • Fully managed, auto-scaling platform.

  • Supports multiple languages and frameworks.

  • Easy integration with Azure DevOps and GitHub.

Cons:

  • Higher costs for production tiers compared to alternatives like Azure Container Apps.

  • Limited control over underlying infrastructure.

Alternatives:

  • Azure Kubernetes Service (AKS): More control but complex setup.

  • Azure Container Apps: Lightweight, serverless containers for microservices.


Module 3: Integrating Azure SQL Database

Overview

Azure SQL Database is a fully managed relational database ideal for structured data like user profiles or photo metadata. We’ll store user and photo details in our app.

Step 1: Create an Azure SQL Database

  1. In the Azure Portal, click Create a resource > SQL Database.

  2. Configure:

    • Database name: PhotoSharingDB.

    • Server: Create a new server (e.g., photosharingserver).

    • Authentication: Use SQL authentication with a secure username and password.

    • Resource Group: Use PhotoSharingRG.

    • Pricing tier: Basic for testing.

  3. Click Review + create, then Create.

Step 2: Connect ASP.NET Core to Azure SQL

  1. Install NuGet packages:

    dotnet add package Microsoft.EntityFrameworkCore.SqlServer
    dotnet add package Microsoft.EntityFrameworkCore.Design
  2. Create a model for photos:

public class Photo
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string BlobUrl { get; set; }
    public DateTime UploadedAt { get; set; }
    public string UserId { get; set; }
}
  1. Create a PhotoContext:

using Microsoft.EntityFrameworkCore;

public class PhotoContext : DbContext
{
    public PhotoContext(DbContextOptions<PhotoContext> options) : base(options) { }
    public DbSet<Photo> Photos { get; set; }
}
  1. Configure the connection string in appsettings.json:

{
  "ConnectionStrings": {
    "PhotoSharingDB": "Server=tcp:photosharingserver.database.windows.net,1433;Initial Catalog=PhotoSharingDB;Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
  }
}
  1. Register the context in Program.cs:

builder.Services.AddDbContext<PhotoContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("PhotoSharingDB")));
  1. Run migrations to create the database schema:

    dotnet ef migrations add InitialCreate
    dotnet ef database update

Step 3: CRUD Operations

Create a controller to manage photos:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

[Route("api/[controller]")]
[ApiController]
public class PhotosController : ControllerBase
{
    private readonly PhotoContext _context;

    public PhotosController(PhotoContext context)
    {
        _context = context;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<Photo>>> GetPhotos()
    {
        return await _context.Photos.ToListAsync();
    }

    [HttpPost]
    public async Task<ActionResult<Photo>> PostPhoto(Photo photo)
    {
        _context.Photos.Add(photo);
        await _context.SaveChangesAsync();
        return CreatedAtAction(nameof(GetPhotos), new { id = photo.Id }, photo);
    }
}

Best Practices:

  • Use Entity Framework Core for ORM to simplify database interactions.

  • Enable connection resiliency in EF Core for transient fault handling:

builder.Services.AddDbContext<PhotoContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("PhotoSharingDB"),
        sqlServerOptions => sqlServerOptions.EnableRetryOnFailure()));
  • Use Azure Key Vault to store connection strings securely.

  • Implement indexing on frequently queried columns (e.g., UserId).

Pros:

  • Fully managed with high availability and automatic backups.

  • Seamless integration with ASP.NET Core via EF Core.

  • Scalable with multiple pricing tiers.

Cons:

  • Can be expensive for high-throughput apps.

  • Limited to relational data models.

Alternatives:

  • Azure Cosmos DB: NoSQL for schemaless data, ideal for high-scale apps.

  • MongoDB Atlas: Third-party NoSQL database with Azure integration.


Module 4: Integrating Azure Blob Storage

Overview

Azure Blob Storage is perfect for storing unstructured data like images. We’ll enable users to upload photos to Blob Storage and retrieve them.

Step 1: Create a Storage Account

  1. In the Azure Portal, click Create a resource > Storage account.

  2. Configure:

    • Resource Group: PhotoSharingRG.

    • Name: photosharingstorage (must be unique).

    • Performance: Standard.

    • Replication: Locally-redundant storage (LRS) for cost savings.

  3. Create a container named photos.

Step 2: Connect to Blob Storage

  1. Install the NuGet package:

    dotnet add package Azure.Storage.Blobs
  2. Add the storage connection string to appsettings.json:

{
  "AzureStorage": {
    "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=photosharingstorage;AccountKey={your_key};EndpointSuffix=core.windows.net",
    "ContainerName": "photos"
  }
}
  1. Create a service to handle Blob Storage operations:

using Azure.Storage.Blobs;
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Threading.Tasks;

public class BlobStorageService
{
    private readonly BlobServiceClient _blobServiceClient;
    private readonly string _containerName;

    public BlobStorageService(IConfiguration configuration)
    {
        _blobServiceClient = new BlobServiceClient(configuration.GetConnectionString("AzureStorage"));
        _containerName = configuration["AzureStorage:ContainerName"];
    }

    public async Task<string> UploadFileAsync(Stream fileStream, string fileName)
    {
        var containerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
        await containerClient.CreateIfNotExistsAsync();
        var blobClient = containerClient.GetBlobClient(fileName);
        await blobClient.UploadAsync(fileStream, true);
        return blobClient.Uri.ToString();
    }
}
  1. Register the service in Program.cs:

builder.Services.AddSingleton<BlobStorageService>();

Step 3: Upload Photos

Update the PhotosController to handle file uploads:

[HttpPost("upload")]
public async Task<ActionResult> UploadPhoto(IFormFile file, [FromServices] BlobStorageService blobService)
{
    if (file == null || file.Length == 0)
        return BadRequest("No file uploaded.");

    using var stream = file.OpenReadStream();
    var blobUrl = await blobService.UploadFileAsync(stream, file.FileName);

    var photo = new Photo
    {
        Title = file.FileName,
        BlobUrl = blobUrl,
        UploadedAt = DateTime.UtcNow,
        UserId = "test-user" // Replace with actual user ID
    };

    _context.Photos.Add(photo);
    await _context.SaveChangesAsync();

    return Ok(new { photo.Id, photo.Title, photo.BlobUrl });
}

Step 4: Display Photos

Create a Razor view (Views/Home/Index.cshtml) to display photos:

@model IEnumerable<Photo>
<h1>Photo Sharing App</h1>
<form asp-action="UploadPhoto" asp-controller="Photos" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit">Upload</button>
</form>
<ul>
    @foreach (var photo in Model)
    {
        <li>
            <h3>@photo.Title</h3>
            <img src="@photo.BlobUrl" alt="@photo.Title" style="max-width: 200px;" />
        </li>
    }
</ul>

Best Practices:

  • Use SAS tokens for secure, temporary access to blobs.

  • Implement retry policies for transient failures:

var blobOptions = new BlobClientOptions
{
    Retry = { MaxRetries = 3, Delay = TimeSpan.FromSeconds(2) }
};
_blobServiceClient = new BlobServiceClient(connectionString, blobOptions);
  • Organize blobs in containers with meaningful names (e.g., user123/photos).

Pros:

  • Highly scalable for large data volumes.

  • Cost-effective for storing unstructured data.

  • Easy integration with ASP.NET Core.

Cons:

  • Not suitable for structured data.

  • Requires careful management of access keys.

Alternatives:

  • Amazon S3: Similar object storage, but requires AWS integration.

  • Azure Files: For shared file access, less suited for public assets.


Module 5: Advanced Scenarios for Scalability

Overview

To make our app truly scalable, we’ll implement caching, load balancing, and microservices.

Step 1: Add Azure Cache for Redis

  1. Create a Redis cache in Azure Portal:

    • Resource Group: PhotoSharingRG.

    • Name: photosharingcache.

    • SKU: Basic.

  2. Install NuGet package:

    dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis
  3. Configure Redis in Program.cs:

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("AzureRedis");
    options.InstanceName = "PhotoSharingCache";
});
  1. Cache photo metadata:

using Microsoft.Extensions.Caching.Distributed;
using System.Text.Json;

public class PhotoService
{
    private readonly IDistributedCache _cache;
    private readonly PhotoContext _context;

    public PhotoService(IDistributedCache cache, PhotoContext context)
    {
        _cache = cache;
        _context = context;
    }

    public async Task<Photo> GetPhotoAsync(int id)
    {
        var cacheKey = $"photo_{id}";
        var cachedPhoto = await _cache.GetStringAsync(cacheKey);
        if (cachedPhoto != null)
            return JsonSerializer.Deserialize<Photo>(cachedPhoto);

        var photo = await _context.Photos.FindAsync(id);
        if (photo != null)
        {
            await _cache.SetStringAsync(cacheKey, JsonSerializer.Serialize(photo), new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
            });
        }
        return photo;
    }
}

Step 2: Load Balancing with Azure Traffic Manager

  1. Create a Traffic Manager profile in Azure Portal.

  2. Add endpoints (multiple App Service instances in different regions).

  3. Configure routing (e.g., Performance routing for lowest latency).

Step 3: Microservices with Azure Container Apps

  1. Containerize the app using Docker:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["PhotoSharingApp.csproj", "."]
RUN dotnet restore "PhotoSharingApp.csproj"
COPY . .
WORKDIR "/src"
RUN dotnet build "PhotoSharingApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "PhotoSharingApp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "PhotoSharingApp.dll"]
  1. Deploy to Azure Container Apps for serverless scaling.

Best Practices:

  • Use Azure Monitor for performance insights.

  • Implement circuit breakers for resilient microservices.

  • Scale out App Service or Container Apps based on CPU/memory metrics.

Pros:

  • Redis provides low-latency caching.

  • Traffic Manager ensures global distribution.

  • Container Apps offer serverless scalability.

Cons:

  • Redis and Container Apps add costs.

  • Microservices increase complexity.

Alternatives:

  • Azure Service Bus: For message-driven microservices.

  • AWS Elastic Beanstalk: Similar to App Service but in AWS ecosystem.


Module 6: Security and Best Practices

Overview

Security is critical for cloud-native apps. We’ll secure our photo-sharing app with best practices.

Step 1: Secure Connection Strings with Azure Key Vault

  1. Create a Key Vault in Azure Portal (photosharingvault).

  2. Add the SQL and Blob Storage connection strings as secrets.

  3. Configure the App Service to use Key Vault references:

az webapp config appsettings set --name PhotoSharingApp123 --resource-group PhotoSharingRG --settings "ConnectionStrings__PhotoSharingDB=@Microsoft.KeyVault(SecretUri=https://photosharingvault.vault.azure.net/secrets/PhotoSharingDB)"

Step 2: Enable Managed Identity

  1. In the App Service, enable System-assigned managed identity.

  2. Grant the identity access to SQL Database and Blob Storage:

az sql server ad-admin set --resource-group PhotoSharingRG --server-name photosharingserver --display-name PhotoSharingAppIdentity --object-id <managed-identity-object-id>

Step 3: Implement Authentication

Use Microsoft Entra ID for user authentication:

  1. Register the app in Entra ID.

  2. Configure in Program.cs:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
  1. Add to appsettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "your-tenant-name.onmicrosoft.com",
    "TenantId": "your-tenant-id",
    "ClientId": "your-client-id",
    "CallbackPath": "/signin-oidc"
  }
}

Best Practices:

  • Use HTTPS everywhere (enabled by default in App Service).

  • Implement CORS for secure API access.

  • Regularly rotate secrets in Key Vault.

Pros:

  • Key Vault centralizes secret management.

  • Managed identities eliminate credential exposure.

  • Entra ID provides enterprise-grade authentication.

Cons:

  • Additional setup time for security features.

  • Entra ID requires tenant configuration.

Alternatives:

  • AWS Secrets Manager: Similar to Key Vault.

  • Okta: Third-party identity provider.


Conclusion

By integrating Azure App Service, SQL Database, Blob Storage, and advanced features like Redis and Container Apps, you’ve built a scalable, secure, and cloud-native photo-sharing app with ASP.NET Core. This tutorial covered everything from basic setup to advanced microservices, with practical code examples and best practices to ensure success in real-world scenarios. Whether you’re deploying a small app or a global platform, Azure and ASP.NET Core provide the tools to scale efficiently while maintaining performance and security.

No comments:

Post a Comment

Thanks for your valuable comment...........
Md. Mominul Islam

Post Bottom Ad

Responsive Ads Here