From a11f8187cb66820534afdcafd118f5c57270c2c5 Mon Sep 17 00:00:00 2001 From: p-kaczynski Date: Mon, 23 Sep 2024 16:03:27 +0100 Subject: [PATCH 1/7] Bump iiif-net and use exposed options with iiif-net derrived collections --- .../Integration/GetCollectionTests.cs | 14 ++--- src/IIIFPresentation/API/API.csproj | 2 +- .../API/Converters/CollectionConverter.cs | 53 +++++++++---------- src/IIIFPresentation/API/Program.cs | 15 +++++- src/IIIFPresentation/Core/Core.csproj | 2 +- .../Core/Response/HttpResponseMessageX.cs | 47 ++++++++-------- .../Models/API/Collection/FlatCollection.cs | 51 +++++++++--------- .../Models/API/Collection/PartOf.cs | 13 ++--- src/IIIFPresentation/Models/Models.csproj | 2 +- .../Repository/Repository.csproj | 2 +- 10 files changed, 106 insertions(+), 95 deletions(-) diff --git a/src/IIIFPresentation/API.Tests/Integration/GetCollectionTests.cs b/src/IIIFPresentation/API.Tests/Integration/GetCollectionTests.cs index 2f5f74f..3cfce24 100644 --- a/src/IIIFPresentation/API.Tests/Integration/GetCollectionTests.cs +++ b/src/IIIFPresentation/API.Tests/Integration/GetCollectionTests.cs @@ -144,7 +144,7 @@ public async Task Get_RootFlat_ReturnsEntryPointFlat_WhenAuthAndHeader() collection!.Id.Should().Be($"http://localhost/1/collections/{RootCollection.Id}"); collection.PublicId.Should().Be("http://localhost/1"); collection.Items!.Count.Should().Be(2); - collection.Items[0].Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); + collection.Items.OfType().First().Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); collection.TotalItems.Should().Be(2); collection.CreatedBy.Should().Be("admin"); collection.Behavior.Should().Contain("public-iiif"); @@ -167,7 +167,7 @@ public async Task Get_ChildFlat_ReturnsEntryPointFlat_WhenCalledByChildId() collection!.Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); collection.PublicId.Should().Be("http://localhost/1/first-child"); collection.Items!.Count.Should().Be(1); - collection.Items[0].Id.Should().Be("http://localhost/1/collections/SecondChildCollection"); + collection.Items.OfType().First().Id.Should().Be("http://localhost/1/collections/SecondChildCollection"); collection.TotalItems.Should().Be(1); collection.CreatedBy.Should().Be("admin"); collection.Behavior.Should().Contain("public-iiif"); @@ -236,7 +236,7 @@ public async Task Get_ChildFlat_ReturnsReducedItems_WhenCalledWithSmallPageSize( collection.View.Page.Should().Be(1); collection.View.TotalPages.Should().Be(2); collection.Items!.Count.Should().Be(1); - collection.Items[0].Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); + collection.Items.OfType().First().Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); } [Fact] @@ -257,7 +257,7 @@ public async Task Get_RootFlat_ReturnsSecondPage_WhenCalledWithSmallPageSize() collection.View.Page.Should().Be(2); collection.View.TotalPages.Should().Be(2); collection.Items!.Count.Should().Be(1); - collection.Items[0].Id.Should().Be("http://localhost/1/collections/NonPublic"); + collection.Items.OfType().First().Id.Should().Be("http://localhost/1/collections/NonPublic"); } [Fact] @@ -322,7 +322,7 @@ public async Task Get_ChildFlat_ReturnsCorrectItem_WhenCalledWithSmallPageSizeAn collection.View.Page.Should().Be(1); collection.View.TotalPages.Should().Be(2); collection.Items!.Count.Should().Be(1); - collection.Items[0].Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); + collection.Items.OfType().First().Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); } [Theory] @@ -348,7 +348,7 @@ public async Task Get_RootFlat_ReturnsFirstPageWithSecondItem_WhenCalledWithSmal collection.View.Page.Should().Be(1); collection.View.TotalPages.Should().Be(2); collection.Items!.Count.Should().Be(1); - collection.Items[0].Id.Should().Be("http://localhost/1/collections/NonPublic"); + collection.Items.OfType().First().Id.Should().Be("http://localhost/1/collections/NonPublic"); } [Fact] @@ -371,6 +371,6 @@ public async Task Get_ChildFlat_IgnoresOrderBy_WhenCalledWithInvalidOrderBy() collection.View.Page.Should().Be(1); collection.View.TotalPages.Should().Be(2); collection.Items!.Count.Should().Be(1); - collection.Items[0].Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); + collection.Items.OfType().First().Id.Should().Be("http://localhost/1/collections/FirstChildCollection"); } } \ No newline at end of file diff --git a/src/IIIFPresentation/API/API.csproj b/src/IIIFPresentation/API/API.csproj index f06703f..ad4306a 100644 --- a/src/IIIFPresentation/API/API.csproj +++ b/src/IIIFPresentation/API/API.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/IIIFPresentation/API/Converters/CollectionConverter.cs b/src/IIIFPresentation/API/Converters/CollectionConverter.cs index 8ce5370..ef82732 100644 --- a/src/IIIFPresentation/API/Converters/CollectionConverter.cs +++ b/src/IIIFPresentation/API/Converters/CollectionConverter.cs @@ -9,20 +9,22 @@ namespace API.Converters; public static class CollectionConverter { - public static Collection ToHierarchicalCollection(this Models.Database.Collections.Collection dbAsset, + public static Collection ToHierarchicalCollection(this Models.Database.Collections.Collection dbAsset, UrlRoots urlRoots, List? items) { var collection = new Collection() { Id = dbAsset.GenerateHierarchicalCollectionId(urlRoots), Label = dbAsset.Label, - Items = items != null ? items.Select(x => new Collection() - { - Id = x.GenerateHierarchicalCollectionId(urlRoots), - Label = x.Label - }).ToList() : [] + Items = items != null + ? items.Select(x => new Collection() + { + Id = x.GenerateHierarchicalCollectionId(urlRoots), + Label = x.Label + }).ToList() + : [] }; - + collection.EnsurePresentation3Context(); return collection; @@ -32,10 +34,10 @@ public static FlatCollection ToFlatCollection(this Models.Database.Collections.C UrlRoots urlRoots, int pageSize, int currentPage, int totalItems, List? items, string? orderQueryParam = null) { - var totalPages = (int)Math.Ceiling(totalItems == 0 ? 1 : (double)totalItems / pageSize); + var totalPages = (int) Math.Ceiling(totalItems == 0 ? 1 : (double) totalItems / pageSize); var orderQueryParamConverted = string.IsNullOrEmpty(orderQueryParam) ? string.Empty : $"&{orderQueryParam}"; - + return new FlatCollection() { Id = dbAsset.GenerateFlatCollectionId(urlRoots), @@ -49,7 +51,7 @@ public static FlatCollection ToFlatCollection(this Models.Database.Collections.C Behavior = new List() .AppendIf(dbAsset.IsPublic, Behavior.IsPublic) .AppendIf(dbAsset.IsStorageCollection, Behavior.IsStorageCollection), - Type = PresentationType.Collection, + PresentationType = PresentationType.Collection, Slug = dbAsset.Slug, Parent = dbAsset.Parent != null ? dbAsset.GenerateFlatCollectionParent(urlRoots) @@ -57,24 +59,22 @@ public static FlatCollection ToFlatCollection(this Models.Database.Collections.C ItemsOrder = dbAsset.ItemsOrder, Items = items != null - ? items.Select(i => new Item + ? items.Select(i => (ICollectionItem) new Collection() { Id = i.GenerateFlatCollectionId(urlRoots), - Label = i.Label, - Type = PresentationType.Collection + Label = i.Label }).ToList() : [], PartOf = dbAsset.Parent != null - ? new List - { - new() + ? + [ + new PartOf(nameof(PresentationType.Collection)) { Id = $"{urlRoots.BaseUrl}/{dbAsset.CustomerId}/{dbAsset.Parent}", - Label = dbAsset.Label, - Type = PresentationType.Collection + Label = dbAsset.Label } - } + ] : null, TotalItems = totalItems, @@ -83,20 +83,18 @@ public static FlatCollection ToFlatCollection(this Models.Database.Collections.C SeeAlso = [ - new() + new(nameof(PresentationType.Collection)) { Id = dbAsset.GenerateHierarchicalCollectionId(urlRoots), - Type = PresentationType.Collection, Label = dbAsset.Label, - Profile = ["Public"] + Profile = "Public" }, - new() + new(nameof(PresentationType.Collection)) { Id = $"{dbAsset.GenerateHierarchicalCollectionId(urlRoots)}/iiif", - Type = PresentationType.Collection, Label = dbAsset.Label, - Profile = ["api-hierarchical"] + Profile = "api-hierarchical" } ], @@ -123,7 +121,8 @@ private static View GenerateView(Models.Database.Collections.Collection dbAsset, if (currentPage > 1) { view.First = dbAsset.GenerateFlatCollectionViewFirst(urlRoots, pageSize, orderQueryParam); - view.Previous = dbAsset.GenerateFlatCollectionViewPrevious(urlRoots, currentPage, pageSize, orderQueryParam); + view.Previous = + dbAsset.GenerateFlatCollectionViewPrevious(urlRoots, currentPage, pageSize, orderQueryParam); } if (totalPages > currentPage) @@ -131,7 +130,7 @@ private static View GenerateView(Models.Database.Collections.Collection dbAsset, view.Next = dbAsset.GenerateFlatCollectionViewNext(urlRoots, currentPage, pageSize, orderQueryParam); view.Last = dbAsset.GenerateFlatCollectionViewLast(urlRoots, totalPages, pageSize, orderQueryParam); } - + return view; } } \ No newline at end of file diff --git a/src/IIIFPresentation/API/Program.cs b/src/IIIFPresentation/API/Program.cs index 243b3a1..0c60911 100644 --- a/src/IIIFPresentation/API/Program.cs +++ b/src/IIIFPresentation/API/Program.cs @@ -1,9 +1,14 @@ +using System.Runtime.Serialization; using System.Text.Json.Serialization; using API.Features.Storage.Validators; using API.Infrastructure; using API.Settings; +using Core.Response; +using IIIF.Presentation.V3; using Microsoft.AspNetCore.HttpOverrides; +using Models.API.Collection; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Repository; using Serilog; @@ -38,7 +43,7 @@ opts.ForwardedHeaders = ForwardedHeaders.XForwardedHost | ForwardedHeaders.XForwardedProto; }); -builder.Services.ConfigureHttpJsonOptions( options => +builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.WriteIndented = true; options.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; @@ -46,6 +51,14 @@ builder.Services.AddOptionsWithValidateOnStart(); +#pragma warning disable SYSLIB0050 +HttpResponseMessageX.SerializationContext = new StreamingContext(StreamingContextStates.All, + new Dictionary> + { + [nameof(FlatCollection)] = _ => new FlatCollection {Slug = string.Empty} + }); +#pragma warning restore SYSLIB0050 + var app = builder.Build(); app.UseForwardedHeaders(); diff --git a/src/IIIFPresentation/Core/Core.csproj b/src/IIIFPresentation/Core/Core.csproj index 826a536..9b9a652 100644 --- a/src/IIIFPresentation/Core/Core.csproj +++ b/src/IIIFPresentation/Core/Core.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs b/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs index 62cdc21..e4ac469 100644 --- a/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs +++ b/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs @@ -1,4 +1,5 @@ -using Core.Exceptions; +using System.Runtime.Serialization; +using Core.Exceptions; using IIIF; using IIIF.Serialisation; using Newtonsoft.Json; @@ -7,6 +8,8 @@ namespace Core.Response; public static class HttpResponseMessageX { + public static StreamingContext? SerializationContext { get; set; } + /// /// Read HttpResponseMessage as JSON using Newtonsoft for conversion. /// @@ -23,10 +26,10 @@ public static class HttpResponseMessageX if (!response.IsJsonResponse()) return default; var contentStream = await response.Content.ReadAsStreamAsync(); - + return contentStream.FromJsonStream(); } - + /// /// Read HttpResponseMessage as JSON using Newtonsoft for conversion. /// @@ -43,22 +46,19 @@ public static class HttpResponseMessageX if (!response.IsJsonResponse()) return default; var contentStream = await response.Content.ReadAsStreamAsync(); - + using var streamReader = new StreamReader(contentStream); - using var jsonReader = new JsonTextReader(streamReader); + await using var jsonReader = new JsonTextReader(streamReader); + + settings ??= new(IIIFSerialiserX.DeserializerSettings); + if (SerializationContext.HasValue) + settings.Context = SerializationContext.Value; + + var serializer = JsonSerializer.Create(settings); - JsonSerializer serializer = new(); - if (settings == null) return serializer.Deserialize(jsonReader); - - if (settings.ContractResolver != null) - { - serializer.ContractResolver = settings.ContractResolver; - } - serializer.NullValueHandling = settings.NullValueHandling; - return serializer.Deserialize(jsonReader); } - + /// /// Check if the object contains a JSON response /// e.g. application/json, application/ld+json @@ -70,15 +70,15 @@ public static bool IsJsonResponse(this HttpResponseMessage response) var mediaType = response.Content.Headers.ContentType?.MediaType; return mediaType != null && mediaType.Contains("json"); } - + public static async Task ReadAsIIIFResponseAsync(this HttpResponseMessage response, JsonSerializerSettings? settings = null) where T : JsonLdBase { - if ((int)response.StatusCode < 400) + if ((int) response.StatusCode < 400) { return await response.ReadWithIIIFContext(true, settings); } - + try { return await response.ReadAsIIIFJsonAsync(false, settings); @@ -88,15 +88,15 @@ public static bool IsJsonResponse(this HttpResponseMessage response) throw new PresentationException("Could not convert response JSON to error", ex); } } - + public static async Task ReadAsPresentationResponseAsync(this HttpResponseMessage response, JsonSerializerSettings? settings = null) { - if ((int)response.StatusCode < 400) + if ((int) response.StatusCode < 400) { return await response.ReadWithContext(true, settings); } - + try { return await response.ReadAsPresentationJsonAsync(false, settings); @@ -115,13 +115,14 @@ public static bool IsJsonResponse(this HttpResponseMessage response) var json = await response.ReadAsIIIFJsonAsync(ensureSuccess, settings ?? new JsonSerializerSettings()); return json; } - + private static async Task ReadWithContext( this HttpResponseMessage response, bool ensureSuccess, JsonSerializerSettings? settings) { - var json = await response.ReadAsPresentationJsonAsync(ensureSuccess, settings ?? new JsonSerializerSettings()); + var json = await response.ReadAsPresentationJsonAsync(ensureSuccess, + settings ?? new JsonSerializerSettings(IIIFSerialiserX.DeserializerSettings)); return json; } } \ No newline at end of file diff --git a/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs b/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs index 1dc1bd4..848a1b3 100644 --- a/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs +++ b/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs @@ -1,48 +1,45 @@ -using IIIF.Presentation.V3.Strings; +using IIIF.Presentation.V3; +using IIIF.Presentation.V3.Strings; using Newtonsoft.Json; namespace Models.API.Collection; -public class FlatCollection +public class FlatCollection : IIIF.Presentation.V3.Collection { [JsonProperty("@context")] - public List? Context { get; set; } - - public string? Id { get; set; } - - public string? PublicId { get; set; } - - public PresentationType Type { get; set; } + public new List? Context + { + get => base.Context as List; + set => base.Context = value; + } + + #region Overrides of Collection - public List Behavior { get; set; } = new (); + public override string Type { get; } = nameof(FlatCollection); - public LanguageMap? Label { get; set; } + #endregion + + public string? PublicId { get; set; } + + public PresentationType PresentationType { get; set; } public required string Slug { get; set; } - + public string? Parent { get; set; } - + public int? ItemsOrder { get; set; } - - public List? Items { get; set; } - - public List? PartOf { get; set; } - + public int TotalItems { get; set; } public View? View { get; set; } - - public List? SeeAlso { get; set; } - + public DateTime Created { get; set; } - + public DateTime Modified { get; set; } - + public string? CreatedBy { get; set; } - + public string? ModifiedBy { get; set; } - + public string? Tags { get; set; } - - public string? Thumbnail { get; set; } } \ No newline at end of file diff --git a/src/IIIFPresentation/Models/API/Collection/PartOf.cs b/src/IIIFPresentation/Models/API/Collection/PartOf.cs index 8c3e53a..ff5da5a 100644 --- a/src/IIIFPresentation/Models/API/Collection/PartOf.cs +++ b/src/IIIFPresentation/Models/API/Collection/PartOf.cs @@ -1,12 +1,13 @@ -using IIIF.Presentation.V3.Strings; +using IIIF.Presentation.V3; +using IIIF.Presentation.V3.Strings; namespace Models.API.Collection; -public class PartOf +public class PartOf(string type) : ResourceBase { - public required string Id { get; set; } + #region Overrides of ResourceBase - public PresentationType Type { get; set; } - - public LanguageMap? Label { get; set; } + public override string Type { get; } = type; + + #endregion } \ No newline at end of file diff --git a/src/IIIFPresentation/Models/Models.csproj b/src/IIIFPresentation/Models/Models.csproj index 1cae422..15464b0 100644 --- a/src/IIIFPresentation/Models/Models.csproj +++ b/src/IIIFPresentation/Models/Models.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/IIIFPresentation/Repository/Repository.csproj b/src/IIIFPresentation/Repository/Repository.csproj index 13426bb..3627d4b 100644 --- a/src/IIIFPresentation/Repository/Repository.csproj +++ b/src/IIIFPresentation/Repository/Repository.csproj @@ -10,7 +10,7 @@ - + From 3d1c740583aa1ffd243117c121b8a8861d398521 Mon Sep 17 00:00:00 2001 From: p-kaczynski Date: Tue, 24 Sep 2024 16:53:42 +0100 Subject: [PATCH 2/7] Exclude selected properties from returned FlatCollection --- .../API/Converters/CollectionConverter.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/IIIFPresentation/API/Converters/CollectionConverter.cs b/src/IIIFPresentation/API/Converters/CollectionConverter.cs index ef82732..97c5bab 100644 --- a/src/IIIFPresentation/API/Converters/CollectionConverter.cs +++ b/src/IIIFPresentation/API/Converters/CollectionConverter.cs @@ -38,7 +38,7 @@ public static FlatCollection ToFlatCollection(this Models.Database.Collections.C var orderQueryParamConverted = string.IsNullOrEmpty(orderQueryParam) ? string.Empty : $"&{orderQueryParam}"; - return new FlatCollection() + return new() { Id = dbAsset.GenerateFlatCollectionId(urlRoots), Context = new List @@ -47,11 +47,13 @@ public static FlatCollection ToFlatCollection(this Models.Database.Collections.C "http://iiif.io/api/presentation/3/context.json" }, Label = dbAsset.Label, - PublicId = dbAsset.GenerateHierarchicalCollectionId(urlRoots), + // Explicitly excluded from returning + // PublicId = dbAsset.GenerateHierarchicalCollectionId(urlRoots), Behavior = new List() .AppendIf(dbAsset.IsPublic, Behavior.IsPublic) .AppendIf(dbAsset.IsStorageCollection, Behavior.IsStorageCollection), - PresentationType = PresentationType.Collection, + // Explicitly excluded from returning + // PresentationType = PresentationType.Collection, Slug = dbAsset.Slug, Parent = dbAsset.Parent != null ? dbAsset.GenerateFlatCollectionParent(urlRoots) From 975161ba48834d430a9f39f81bc71a8eff358baa Mon Sep 17 00:00:00 2001 From: p-kaczynski Date: Tue, 24 Sep 2024 16:54:24 +0100 Subject: [PATCH 3/7] Remove unused class SeeAlso --- .../Models/API/Collection/SeeAlso.cs | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/IIIFPresentation/Models/API/Collection/SeeAlso.cs diff --git a/src/IIIFPresentation/Models/API/Collection/SeeAlso.cs b/src/IIIFPresentation/Models/API/Collection/SeeAlso.cs deleted file mode 100644 index 596637e..0000000 --- a/src/IIIFPresentation/Models/API/Collection/SeeAlso.cs +++ /dev/null @@ -1,14 +0,0 @@ -using IIIF.Presentation.V3.Strings; - -namespace Models.API.Collection; - -public class SeeAlso -{ - public required string Id { get; set; } - - public PresentationType Type { get; set; } - - public LanguageMap? Label { get; set; } - - public List? Profile { get; set; } -} \ No newline at end of file From dae45f227525d3a3fdfc7bbe5cdb0e2044952329 Mon Sep 17 00:00:00 2001 From: p-kaczynski Date: Tue, 24 Sep 2024 16:55:03 +0100 Subject: [PATCH 4/7] Use spec-correct Type and resolve type manually during deserialization --- src/IIIFPresentation/API/Program.cs | 8 -------- .../Core/Response/HttpResponseMessageX.cs | 10 ++++++---- .../Models/API/Collection/FlatCollection.cs | 12 ++---------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/IIIFPresentation/API/Program.cs b/src/IIIFPresentation/API/Program.cs index 0c60911..710e9e3 100644 --- a/src/IIIFPresentation/API/Program.cs +++ b/src/IIIFPresentation/API/Program.cs @@ -51,14 +51,6 @@ builder.Services.AddOptionsWithValidateOnStart(); -#pragma warning disable SYSLIB0050 -HttpResponseMessageX.SerializationContext = new StreamingContext(StreamingContextStates.All, - new Dictionary> - { - [nameof(FlatCollection)] = _ => new FlatCollection {Slug = string.Empty} - }); -#pragma warning restore SYSLIB0050 - var app = builder.Build(); app.UseForwardedHeaders(); diff --git a/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs b/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs index e4ac469..1b29692 100644 --- a/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs +++ b/src/IIIFPresentation/Core/Response/HttpResponseMessageX.cs @@ -39,7 +39,7 @@ public static class HttpResponseMessageX /// Type to convert response to /// Converted Http response. public static async Task ReadAsPresentationJsonAsync(this HttpResponseMessage response, - bool ensureSuccess = true, JsonSerializerSettings? settings = null) + bool ensureSuccess = true, JsonSerializerSettings? settings = null) where T : new() { if (ensureSuccess) response.EnsureSuccessStatusCode(); @@ -56,7 +56,9 @@ public static class HttpResponseMessageX var serializer = JsonSerializer.Create(settings); - return serializer.Deserialize(jsonReader); + var result = new T(); + serializer.Populate(jsonReader, result); + return result; } /// @@ -90,7 +92,7 @@ public static bool IsJsonResponse(this HttpResponseMessage response) } public static async Task ReadAsPresentationResponseAsync(this HttpResponseMessage response, - JsonSerializerSettings? settings = null) + JsonSerializerSettings? settings = null) where T : new() { if ((int) response.StatusCode < 400) { @@ -119,7 +121,7 @@ public static bool IsJsonResponse(this HttpResponseMessage response) private static async Task ReadWithContext( this HttpResponseMessage response, bool ensureSuccess, - JsonSerializerSettings? settings) + JsonSerializerSettings? settings) where T : new() { var json = await response.ReadAsPresentationJsonAsync(ensureSuccess, settings ?? new JsonSerializerSettings(IIIFSerialiserX.DeserializerSettings)); diff --git a/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs b/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs index 848a1b3..3e18954 100644 --- a/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs +++ b/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs @@ -1,6 +1,4 @@ -using IIIF.Presentation.V3; -using IIIF.Presentation.V3.Strings; -using Newtonsoft.Json; +using Newtonsoft.Json; namespace Models.API.Collection; @@ -13,17 +11,11 @@ public class FlatCollection : IIIF.Presentation.V3.Collection set => base.Context = value; } - #region Overrides of Collection - - public override string Type { get; } = nameof(FlatCollection); - - #endregion - public string? PublicId { get; set; } public PresentationType PresentationType { get; set; } - public required string Slug { get; set; } + [JsonRequired] public string? Slug { get; set; } public string? Parent { get; set; } From 90d74859719db5be39296460ac1c710a6b6ea0dc Mon Sep 17 00:00:00 2001 From: p-kaczynski Date: Tue, 24 Sep 2024 17:04:54 +0100 Subject: [PATCH 5/7] Update CollectionConverter.cs --- src/IIIFPresentation/API/Converters/CollectionConverter.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/IIIFPresentation/API/Converters/CollectionConverter.cs b/src/IIIFPresentation/API/Converters/CollectionConverter.cs index 97c5bab..db6ea1b 100644 --- a/src/IIIFPresentation/API/Converters/CollectionConverter.cs +++ b/src/IIIFPresentation/API/Converters/CollectionConverter.cs @@ -47,13 +47,10 @@ public static FlatCollection ToFlatCollection(this Models.Database.Collections.C "http://iiif.io/api/presentation/3/context.json" }, Label = dbAsset.Label, - // Explicitly excluded from returning - // PublicId = dbAsset.GenerateHierarchicalCollectionId(urlRoots), + PublicId = dbAsset.GenerateHierarchicalCollectionId(urlRoots), Behavior = new List() .AppendIf(dbAsset.IsPublic, Behavior.IsPublic) .AppendIf(dbAsset.IsStorageCollection, Behavior.IsStorageCollection), - // Explicitly excluded from returning - // PresentationType = PresentationType.Collection, Slug = dbAsset.Slug, Parent = dbAsset.Parent != null ? dbAsset.GenerateFlatCollectionParent(urlRoots) From 5ec57f2866e84696d3edfaf84da9ff6ded0b4f98 Mon Sep 17 00:00:00 2001 From: p-kaczynski Date: Wed, 25 Sep 2024 10:21:22 +0100 Subject: [PATCH 6/7] Update View.cs --- src/IIIFPresentation/Models/API/Collection/View.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/IIIFPresentation/Models/API/Collection/View.cs b/src/IIIFPresentation/Models/API/Collection/View.cs index edf6e92..5a52ed4 100644 --- a/src/IIIFPresentation/Models/API/Collection/View.cs +++ b/src/IIIFPresentation/Models/API/Collection/View.cs @@ -1,13 +1,13 @@ -using System.Text.Json.Serialization; +using Newtonsoft.Json; namespace Models.API.Collection; public class View { - [JsonPropertyName("@id")] + [JsonProperty("@id")] public required string Id { get; set; } - [JsonPropertyName("@type")] + [JsonProperty("@type")] public PresentationType Type { get; set; } public int Page { get; set; } From d7f9c280d6a60e65499abe9fe4b15785cac4f9c9 Mon Sep 17 00:00:00 2001 From: p-kaczynski Date: Wed, 25 Sep 2024 10:34:05 +0100 Subject: [PATCH 7/7] PresentationType as string --- src/IIIFPresentation/Models/API/Collection/FlatCollection.cs | 2 -- src/IIIFPresentation/Models/API/Collection/View.cs | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs b/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs index 3e18954..0f905fb 100644 --- a/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs +++ b/src/IIIFPresentation/Models/API/Collection/FlatCollection.cs @@ -13,8 +13,6 @@ public class FlatCollection : IIIF.Presentation.V3.Collection public string? PublicId { get; set; } - public PresentationType PresentationType { get; set; } - [JsonRequired] public string? Slug { get; set; } public string? Parent { get; set; } diff --git a/src/IIIFPresentation/Models/API/Collection/View.cs b/src/IIIFPresentation/Models/API/Collection/View.cs index 5a52ed4..00ca10c 100644 --- a/src/IIIFPresentation/Models/API/Collection/View.cs +++ b/src/IIIFPresentation/Models/API/Collection/View.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Converters; namespace Models.API.Collection; @@ -7,7 +8,8 @@ public class View [JsonProperty("@id")] public required string Id { get; set; } - [JsonProperty("@type")] + [JsonProperty("@type")] + [JsonConverter(typeof(StringEnumConverter))] public PresentationType Type { get; set; } public int Page { get; set; }