From 8bb26a029673c6a92989fe0fdb40028a7fed70b2 Mon Sep 17 00:00:00 2001 From: Anas Rashid Date: Mon, 5 Oct 2026 00:06:28 +0200 Subject: [PATCH] Poet images: placeholder instead of broken images (#4) - poet ImageUrl always points at the API image endpoint - endpoint serves a neutral SVG placeholder when a poet has no portrait - public data export: poet image URLs use our API (WebServiceUrl), not ganjoor.net Co-Authored-By: Claude Opus 5.5 --- RMuseum/Controllers/DivanController.cs | 12 +++++++++++- .../DivanService-PublicDataExport.cs | 2 +- RMuseum/Services/Implementation/DivanService.cs | 6 +++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/RMuseum/Controllers/DivanController.cs b/RMuseum/Controllers/DivanController.cs index f462401b..43b72d7e 100644 --- a/RMuseum/Controllers/DivanController.cs +++ b/RMuseum/Controllers/DivanController.cs @@ -315,6 +315,12 @@ namespace RMuseum.Controllers return Ok(); } + private const string PoetImagePlaceholderSvg = + "" + + "" + + "" + + ""; + /// /// get poet image with png ext /// @@ -355,7 +361,11 @@ namespace RMuseum.Controllers return BadRequest(poet.ExceptionString); if (poet.Result == Guid.Empty) - return NotFound(); + { + // divan: portraits are optional (deferred); serve a neutral placeholder instead of a broken image + Response.Headers.CacheControl = "public,max-age=86400"; + return Content(PoetImagePlaceholderSvg, "image/svg+xml"); + } RServiceResult img = diff --git a/RMuseum/Services/Implementation/DivanService-Partials/DivanService-PublicDataExport.cs b/RMuseum/Services/Implementation/DivanService-Partials/DivanService-PublicDataExport.cs index 72b8234d..41e99a3f 100644 --- a/RMuseum/Services/Implementation/DivanService-Partials/DivanService-PublicDataExport.cs +++ b/RMuseum/Services/Implementation/DivanService-Partials/DivanService-PublicDataExport.cs @@ -253,7 +253,7 @@ namespace RMuseum.Services.Implementation Nickname = poet.Nickname, Description = poet.Description, FullUrl = catPoet.FullUrl, - ImageUrl = poet.RImageId == null ? null : $"https://ganjoor.net/api/divan/poet/image{catPoet.FullUrl}.gif", + ImageUrl = poet.RImageId == null ? null : $"{WebServiceUrl.Url}/api/divan/poet/image{catPoet.FullUrl}.gif", // divan: own API, not ganjoor.net BirthYearInLHijri = poet.BirthYearInLHijri, ValidBirthDate = poet.ValidBirthDate, DeathYearInLHijri = poet.DeathYearInLHijri, diff --git a/RMuseum/Services/Implementation/DivanService.cs b/RMuseum/Services/Implementation/DivanService.cs index 4c28a315..4147b70c 100644 --- a/RMuseum/Services/Implementation/DivanService.cs +++ b/RMuseum/Services/Implementation/DivanService.cs @@ -62,7 +62,7 @@ namespace RMuseum.Services.Implementation RootCatId = cat.Id, Nickname = poet.Nickname, Published = poet.Published, - ImageUrl = poet.RImageId == null ? "" : $"/api/divan/poet/image{cat.FullUrl}.gif", + ImageUrl = $"/api/divan/poet/image{cat.FullUrl}.gif", BirthYearInLHijri = poet.BirthYearInLHijri, DeathYearInLHijri = poet.DeathYearInLHijri, ValidBirthDate = poet.ValidBirthDate, @@ -453,7 +453,7 @@ namespace RMuseum.Services.Implementation RootCatId = context.DivanCategories.Where(c => c.PoetId == poet.Id && c.ParentId == null).Single().Id, Nickname = poet.Nickname, Published = poet.Published, - ImageUrl = poet.RImageId == null ? "" : $"/api/divan/poet/image{context.DivanCategories.Where(c => c.PoetId == poet.Id && c.ParentId == null).Single().FullUrl}.gif", + ImageUrl = $"/api/divan/poet/image{context.DivanCategories.Where(c => c.PoetId == poet.Id && c.ParentId == null).Single().FullUrl}.gif", BirthYearInLHijri = poet.BirthYearInLHijri, DeathYearInLHijri = poet.DeathYearInLHijri, ValidBirthDate = poet.ValidBirthDate, @@ -623,7 +623,7 @@ namespace RMuseum.Services.Implementation RootCatId = cat.Id, Nickname = poet.Nickname, Published = poet.Published, - ImageUrl = poet.RImageId == null ? "" : $"/api/divan/poet/image{cat.FullUrl}.gif", + ImageUrl = $"/api/divan/poet/image{cat.FullUrl}.gif", BirthYearInLHijri = poet.BirthYearInLHijri, ValidBirthDate = poet.ValidBirthDate, ValidDeathDate = poet.ValidDeathDate,