Skip to content

Commit

Permalink
Merge branch 'main' into hishamco/deployment-source
Browse files Browse the repository at this point in the history
  • Loading branch information
hishamco authored Oct 9, 2024
2 parents 8f817cc + 5770ac8 commit 0fcd568
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using OrchardCore.ContentManagement;
using OrchardCore.ContentManagement.Handlers;
using OrchardCore.ContentManagement.Metadata;
using OrchardCore.DisplayManagement.ModelBinding;
using OrchardCore.Json;
using OrchardCore.Modules;

namespace OrchardCore.Contents.Endpoints.Api;
Expand Down Expand Up @@ -37,6 +39,7 @@ private static async Task<IResult> HandleAsync(
IContentDefinitionManager contentDefinitionManager,
IUpdateModelAccessor updateModelAccessor,
HttpContext httpContext,
IOptions<DocumentJsonSerializerOptions> options,
bool draft = false)
{
if (!await authorizationService.AuthorizeAsync(httpContext.User, CommonPermissions.AccessContentApi))
Expand Down Expand Up @@ -123,7 +126,7 @@ private static async Task<IResult> HandleAsync(
await contentManager.SaveDraftAsync(contentItem);
}

return TypedResults.Ok(contentItem);
return Results.Json(contentItem, options.Value.SerializerOptions);
}

private static void AddValidationErrorsToModelState(ContentValidateResult result, ModelStateDictionary modelState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using OrchardCore.ContentManagement;
using OrchardCore.Json;
using OrchardCore.Modules;

namespace OrchardCore.Contents.Endpoints.Api;
Expand All @@ -23,7 +25,8 @@ private static async Task<IResult> HandleAsync(
string contentItemId,
IContentManager contentManager,
IAuthorizationService authorizationService,
HttpContext httpContext)
HttpContext httpContext,
IOptions<DocumentJsonSerializerOptions> options)
{
if (!await authorizationService.AuthorizeAsync(httpContext.User, CommonPermissions.AccessContentApi))
{
Expand All @@ -44,6 +47,6 @@ private static async Task<IResult> HandleAsync(

await contentManager.RemoveAsync(contentItem);

return TypedResults.Ok(contentItem);
return Results.Json(contentItem, options.Value.SerializerOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using OrchardCore.ContentManagement;
using OrchardCore.Json;
using OrchardCore.Modules;

namespace OrchardCore.Contents.Endpoints.Api;
Expand All @@ -23,7 +25,8 @@ private static async Task<IResult> HandleAsync(
string contentItemId,
IContentManager contentManager,
IAuthorizationService authorizationService,
HttpContext httpContext)
HttpContext httpContext,
IOptions<DocumentJsonSerializerOptions> options)
{
if (!await authorizationService.AuthorizeAsync(httpContext.User, CommonPermissions.AccessContentApi))
{
Expand All @@ -42,6 +45,6 @@ private static async Task<IResult> HandleAsync(
return httpContext.ChallengeOrForbid("Api");
}

return TypedResults.Ok(contentItem);
return Results.Json(contentItem, options.Value.SerializerOptions);
}
}
2 changes: 2 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Contents/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using OrchardCore.Contents.AdminNodes;
using OrchardCore.Contents.AuditTrail.Settings;
using OrchardCore.Contents.Controllers;
using OrchardCore.Contents.Core;
using OrchardCore.Contents.Deployment;
using OrchardCore.Contents.Drivers;
using OrchardCore.Contents.Endpoints.Api;
Expand Down Expand Up @@ -59,6 +60,7 @@ public sealed class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddContentServices();
services.AddSingleton<IAnchorTag, ContentAnchorTag>();

services.Configure<LiquidViewOptions>(o =>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OrchardCore.Contents.Core.Services;

namespace OrchardCore.Contents.Core;

public static class ServiceCollectionExtensions
{
public static IServiceCollection AddContentServices(this IServiceCollection services)
{
services.AddTransient<IConfigureOptions<MvcOptions>, MvcOptionsConfiguration>();

return services;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc.Formatters;
using OrchardCore.ContentManagement;

namespace OrchardCore.Contents.Core.Services;

public sealed class ContentSystemTextJsonOutputFormatter : SystemTextJsonOutputFormatter
{
public ContentSystemTextJsonOutputFormatter(JsonSerializerOptions jsonSerializerOptions)
: base(jsonSerializerOptions)
{
}

protected override bool CanWriteType(Type type)
=> typeof(IContent).IsAssignableFrom(type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using OrchardCore.Json;

namespace OrchardCore.Contents.Core.Services;

internal sealed class MvcOptionsConfiguration : IConfigureOptions<MvcOptions>
{
private readonly DocumentJsonSerializerOptions _documentOptions;

public MvcOptionsConfiguration(IOptions<DocumentJsonSerializerOptions> documentOptions)
{
_documentOptions = documentOptions.Value;
}

public void Configure(MvcOptions options)
{
options.OutputFormatters.Insert(0, new ContentSystemTextJsonOutputFormatter(_documentOptions.SerializerOptions));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc.Formatters;
using OrchardCore.Data.Documents;
using OrchardCore.Entities;

namespace OrchardCore.Json;

public sealed class DocumentSystemTextJsonOutputFormatter : SystemTextJsonOutputFormatter
{
public DocumentSystemTextJsonOutputFormatter(JsonSerializerOptions jsonSerializerOptions)
: base(jsonSerializerOptions)
{
}

protected override bool CanWriteType(Type type)
=> typeof(IDocument).IsAssignableFrom(type) ||
typeof(IEntity).IsAssignableFrom(type);
}
20 changes: 20 additions & 0 deletions src/OrchardCore/OrchardCore/Extensions/MvcOptionsConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using OrchardCore.Json;

namespace OrchardCore.Extensions;

internal sealed class MvcOptionsConfiguration : IConfigureOptions<MvcOptions>
{
private readonly DocumentJsonSerializerOptions _documentOptions;

public MvcOptionsConfiguration(IOptions<DocumentJsonSerializerOptions> documentOptions)
{
_documentOptions = documentOptions.Value;
}

public void Configure(MvcOptions options)
{
options.OutputFormatters.Insert(0, new DocumentSystemTextJsonOutputFormatter(_documentOptions.SerializerOptions));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Localization;
Expand Down Expand Up @@ -148,9 +149,8 @@ private static void AddDefaultServices(OrchardCoreBuilder builder)
services.AddScoped<ICalendarSelector, DefaultCalendarSelector>();

services.AddSingleton<IPoweredByMiddlewareOptions, PoweredByMiddlewareOptions>();

services.AddTransient<IConfigureOptions<Microsoft.AspNetCore.Http.Json.JsonOptions>, JsonOptionsConfigurations>();
services.AddTransient<IConfigureOptions<DocumentJsonSerializerOptions>, DocumentJsonSerializerOptionsConfiguration>();
services.AddTransient<IConfigureOptions<MvcOptions>, MvcOptionsConfiguration>();

services.AddScoped<IOrchardHelper, DefaultOrchardHelper>();
services.AddSingleton<IClientIPAddressAccessor, DefaultClientIPAddressAccessor>();
Expand Down
18 changes: 16 additions & 2 deletions src/docs/releases/2.1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,21 @@

Release date: Not yet released

## Change Logs
Here's the updated version to include the reference to `IEntity` implementations:

## Change Log

### Behavioral Changes

#### `JsonOptions` Configuration

A key change in version 2.0 is the shift from **Newtonsoft.Json** to **System.Text.Json**. Previously, we configured the default `JsonOptions` to match the settings used for document serialization. In this release, however, we’ve reverted that approach, and the `JsonOptions` are no longer configured by default. This change provides greater flexibility, allowing you to customize JSON serialization as needed.

If your Minimal API returns YesSql documents, entities (implementations of `IEntity`) or content (implementations of `IContent`), such as `ContentItem`, `User`, `Query`, or `Notification`, you may need to use `DocumentJsonSerializerOptions` for proper serialization. For example, when using Minimal API, instead of returning the result with `TypedResults.Ok(entity)`, you should use `Results.Json(entity, options.Value.SerializerOptions)`, resolving `IOptions<DocumentJsonSerializerOptions>` from the IoC container.

For scenarios using `ApiController` to return YesSql documents or entities, we’ve introduced new output formatters, `DocumentSystemTextJsonOutputFormatter` and `ContentSystemTextJsonOutputFormatter`, to automatically handle document serialization to JSON correctly.

These changes are non-breaking and you shouldn't need to change working 2.0.x code.

### Users Feature

Expand Down Expand Up @@ -108,7 +122,7 @@ Additionally, the configuration provider key for the default provider has change

### Autoroute Feature

### Content Item Shape Alternates Based on Alias and Slug
#### Content Item Shape Alternates Based on Alias and Slug

Content item shapes can be overridden by their alias if `AliasPart` is attached or by their slug if `AutoroutePart` is attached. For examples, refer to the [docs](../reference/modules/Templates/README.md).

Expand Down

0 comments on commit 0fcd568

Please sign in to comment.