Upload Profile Photos to Blob Storage
Users can finally set a profile photo. The new endpoint accepts an image upload, stores it in a profile-photos blob container, and saves the blob URL on the user so the web and mobile apps can show it. The container is created at startup if it doesn't exist. There's a test for a successful upload.
Asrc/Api/Controllers/ProfilePhotoController.cs1 of 3
Files Changed
src/Api/Controllers/
src/Api/
tests/Api.Tests/
src/Api/Controllers/ProfilePhotoController.cs
C# · Click a line number to comment · Tap a line to comment@@ -0,0 +1,37 @@
Added: using Azure.Storage.Blobs;
Added: using Azure.Storage.Blobs.Models;
Added: using Microsoft.AspNetCore.Authorization;
Added: using Microsoft.AspNetCore.Mvc;
Added:
Added: namespace Api.Controllers;
Added:
Added: [ApiController]
Added: [Authorize]
Added: [Route("api/profile/photo")]
Added: public class ProfilePhotoController : ControllerBase
Added: {
Added: private readonly BlobContainerClient _photos;
Added: private readonly AppDbContext _db;
Added:
Added: public ProfilePhotoController(BlobContainerClient photos, AppDbContext db)
Added: {
Added: _photos = photos;
Added: _db = db;
Added: }
Added:
Added: [HttpPost]
Added: public IActionResult Upload(IFormFile file)
Added: {
Added: if (!file.ContentType.StartsWith("image/"))
Added: return BadRequest("Only images are allowed.");
Added:
Added: var blob = _photos.GetBlobClient(file.FileName);
Added: blob.Upload(file.OpenReadStream(), new BlobHttpHeaders { ContentType = file.ContentType });
Added:
Added: var user = _db.Users.Find(User.GetUserId());
Added: user.PhotoUrl = blob.Uri.ToString();
Added: _db.SaveChanges();
Added:
Added: return Ok(new { url = user.PhotoUrl });
Added: }
Added: }
src/Api/Program.cs
C# · Click a line number to comment · Tap a line to comment@@ -1,8 +1,14 @@
using Api;
Added: using Azure.Storage.Blobs;
Added: using Azure.Storage.Blobs.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddDbContext<AppDbContext>();
Added:
Added: var photos = new BlobContainerClient(builder.Configuration["Storage:ConnectionString"], "profile-photos");
Added: photos.CreateIfNotExists(PublicAccessType.BlobContainer);
Added: builder.Services.AddSingleton(photos);
var app = builder.Build();
tests/Api.Tests/ProfilePhotoTests.cs
C# · Click a line number to comment · Tap a line to comment@@ -0,0 +1,14 @@
Added: using Api.Controllers;
Added: using Xunit;
Added:
Added: public class ProfilePhotoTests : ApiTestBase
Added: {
Added: [Fact]
Added: public async Task Upload_StoresThePhotoAndReturnsItsUrl()
Added: {
Added: var response = await PostPhoto("avatar.png", "image/png", TestImages.Png);
Added:
Added: response.EnsureSuccessStatusCode();
Added: Assert.Contains("avatar.png", await response.Content.ReadAsStringAsync());
Added: }
Added: }