From f9e58b0f1f8549d8f9408a1131667d76d3c1f7a6 Mon Sep 17 00:00:00 2001 From: cihandeniz Date: Tue, 11 Jun 2024 11:30:45 +0300 Subject: [PATCH 1/4] init `bug/lazy-error` - add release notes --- unreleased.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/unreleased.md b/unreleased.md index c972d156a..1f1c2e42b 100644 --- a/unreleased.md +++ b/unreleased.md @@ -6,3 +6,8 @@ - Root namespace is `Baked` - `Forge` is now `Bake` - `Bluprints` are now `Recipes` +- `Authentication.Disabled` was removed + +## Bugfixes + +- NHibernate proxies were causing serialization error, fixed From 3d398b3ae9290f014e9b147f974a636ac73ae81e Mon Sep 17 00:00:00 2001 From: cihandeniz Date: Tue, 11 Jun 2024 11:57:36 +0300 Subject: [PATCH 2/4] fix proxy serialization error --- .../Orm/AutoMap/AutoMapOrmFeature.cs | 9 ++++++++ .../RestApi/ProxyAwareContractResolver.cs | 17 +++++++++++++++ .../Orm/LazyLoading.cs | 21 +++++++++++++++++++ .../Baked.Test.Recipe.Service/Orm/Child.cs | 3 +++ 4 files changed, 50 insertions(+) create mode 100644 src/recipe/Baked.Recipe.Service.Application/RestApi/ProxyAwareContractResolver.cs create mode 100644 test/recipe/Baked.Test.Recipe.Service.Test/Orm/LazyLoading.cs diff --git a/src/recipe/Baked.Recipe.Service.Application/Orm/AutoMap/AutoMapOrmFeature.cs b/src/recipe/Baked.Recipe.Service.Application/Orm/AutoMap/AutoMapOrmFeature.cs index 46bafecc9..2d2aaea5c 100644 --- a/src/recipe/Baked.Recipe.Service.Application/Orm/AutoMap/AutoMapOrmFeature.cs +++ b/src/recipe/Baked.Recipe.Service.Application/Orm/AutoMap/AutoMapOrmFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.RestApi; using Baked.RestApi.Conventions; using FluentNHibernate.Conventions.Helpers; using FluentNHibernate.Mapping; @@ -8,6 +9,7 @@ using Microsoft.Extensions.Logging; using NHibernate; using NHibernate.Exceptions; +using NHibernate.Proxy; namespace Baked.Orm.AutoMap; @@ -79,6 +81,13 @@ public void Configure(LayerConfigurator configurator) }); }); + configurator.ConfigureMvcNewtonsoftJsonOptions(options => + { + if (options.SerializerSettings.ContractResolver is null) { return; } + + options.SerializerSettings.ContractResolver = new ProxyAwareContractResolver(options.SerializerSettings.ContractResolver); + }); + configurator.ConfigureApiModelConventions(conventions => { var domainModel = configurator.Context.GetDomainModel(); diff --git a/src/recipe/Baked.Recipe.Service.Application/RestApi/ProxyAwareContractResolver.cs b/src/recipe/Baked.Recipe.Service.Application/RestApi/ProxyAwareContractResolver.cs new file mode 100644 index 000000000..ac7eccaa2 --- /dev/null +++ b/src/recipe/Baked.Recipe.Service.Application/RestApi/ProxyAwareContractResolver.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json.Serialization; + +namespace Baked.RestApi; + +public class ProxyAwareContractResolver(IContractResolver _real) + : IContractResolver +{ + public JsonContract ResolveContract(Type type) + { + if (type.IsAssignableTo(typeof(TProxyInterface))) + { + type = type.BaseType ?? throw new($"Proxy type {type.FullName} should have a base type!!"); + } + + return _real.ResolveContract(type); + } +} \ No newline at end of file diff --git a/test/recipe/Baked.Test.Recipe.Service.Test/Orm/LazyLoading.cs b/test/recipe/Baked.Test.Recipe.Service.Test/Orm/LazyLoading.cs new file mode 100644 index 000000000..b07f7be1e --- /dev/null +++ b/test/recipe/Baked.Test.Recipe.Service.Test/Orm/LazyLoading.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; +using System.Net; +using System.Net.Http.Json; + +namespace Baked.Test.Orm; + +public class LazyLoading : TestServiceNfr +{ + [Test] + public async Task Proxy_classes_serialized_correctly() + { + var parentResponse = await Client.PostAsync("/parents", JsonContent.Create(new { name = "test" })); + dynamic? parent = JsonConvert.DeserializeObject(await parentResponse.Content.ReadAsStringAsync()); + + await Client.PostAsync($"/parents/{parent?.id}/children", JsonContent.Create(new { })); + + var response = await Client.GetAsync($"/children"); + + response.StatusCode.ShouldBe(HttpStatusCode.OK); + } +} \ No newline at end of file diff --git a/test/recipe/Baked.Test.Recipe.Service/Orm/Child.cs b/test/recipe/Baked.Test.Recipe.Service/Orm/Child.cs index 6e0d83919..faa835f23 100644 --- a/test/recipe/Baked.Test.Recipe.Service/Orm/Child.cs +++ b/test/recipe/Baked.Test.Recipe.Service/Orm/Child.cs @@ -24,4 +24,7 @@ public class Children(IQueryContext _context) { internal List ByParent(Parent parent) => _context.By(e => e.Parent == parent); + + public List By() => + _context.By(c => true); } \ No newline at end of file From bdb5fa91a5f9f8e16100ace5042941d2ae955317 Mon Sep 17 00:00:00 2001 From: cihandeniz Date: Tue, 11 Jun 2024 12:03:16 +0300 Subject: [PATCH 3/4] improve dotnet restore in docker --- .dockerignore | 19 +++++++++++++++++++ .../Dockerfile | 5 +++++ 2 files changed, 24 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..4ae57a159 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.github +**/.vs +**/.vscode +**/.project +**/*.*proj.user +**/.settings +**/.toolstarget +**/Dockerfile* +**/bin +**/obj +**/*.swp +**/*.md +docs/**/* +research/**/* +samples/**/* diff --git a/test/recipe/Baked.Test.Recipe.Service.Application/Dockerfile b/test/recipe/Baked.Test.Recipe.Service.Application/Dockerfile index 68296e42b..41f3123b6 100644 --- a/test/recipe/Baked.Test.Recipe.Service.Application/Dockerfile +++ b/test/recipe/Baked.Test.Recipe.Service.Application/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.7-labs + FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base ARG ENVIRONMENT=Production @@ -8,6 +10,9 @@ ENV ASPNETCORE_URLS=http://+:80 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS publish +COPY --exclude=**/*.cs --exclude=**/*.json . . +RUN dotnet restore + COPY . . RUN dotnet publish ./test/recipe/Baked.Test.Recipe.Service.Application -c Release -o /app/publish From 74a9bb08832fac188dc1f0f2e12cfeacddbdd32c Mon Sep 17 00:00:00 2001 From: cihandeniz Date: Tue, 11 Jun 2024 12:04:19 +0300 Subject: [PATCH 4/4] remove authentication disabled - add authorization disabled to docs --- docs/features/authorization.md | 8 ++++++++ .../Authentication/AuthenticationConfigurator.cs | 10 ++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/features/authorization.md b/docs/features/authorization.md index cca9a5f3a..244fabd9e 100644 --- a/docs/features/authorization.md +++ b/docs/features/authorization.md @@ -46,3 +46,11 @@ and this handler directly throws; - `UnauthorizedAccessExcetpin` when forbidden instead of using `IAuthenticationHandler` fallback methods. + +## Disabled + +You can disable this feature by calling `Disabled()` method; + +```csharp +c => c.Disabled() +``` diff --git a/src/recipe/Baked.Recipe.Service.Application/Authentication/AuthenticationConfigurator.cs b/src/recipe/Baked.Recipe.Service.Application/Authentication/AuthenticationConfigurator.cs index 91c26e4fe..c7d93e92b 100644 --- a/src/recipe/Baked.Recipe.Service.Application/Authentication/AuthenticationConfigurator.cs +++ b/src/recipe/Baked.Recipe.Service.Application/Authentication/AuthenticationConfigurator.cs @@ -1,9 +1,3 @@ -using Baked.Architecture; +namespace Baked.Authentication; -namespace Baked.Authentication; - -public class AuthenticationConfigurator -{ - public IFeature Disabled() => - Feature.Empty(); -} \ No newline at end of file +public class AuthenticationConfigurator { } \ No newline at end of file