diff --git a/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs b/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs
index 417ed622bd..6654c17981 100644
--- a/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs
+++ b/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs
@@ -1,57 +1,54 @@
using System.Net;
-using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Core.Web;
-namespace Umbraco.Cms.Web.Common.ActionsResults
+namespace Umbraco.Cms.Web.Common.ActionsResults;
+
+///
+/// Returns the Umbraco not found result
+///
+public class PublishedContentNotFoundResult : IActionResult
{
+ private readonly string? _message;
+ private readonly IUmbracoContext _umbracoContext;
+
///
- /// Returns the Umbraco not found result
+ /// Initializes a new instance of the class.
///
- public class PublishedContentNotFoundResult : IActionResult
+ public PublishedContentNotFoundResult(IUmbracoContext umbracoContext, string? message = null)
{
- private readonly IUmbracoContext _umbracoContext;
- private readonly string? _message;
+ _umbracoContext = umbracoContext;
+ _message = message;
+ }
- ///
- /// Initializes a new instance of the class.
- ///
- public PublishedContentNotFoundResult(IUmbracoContext umbracoContext, string? message = null)
+ ///
+ public async Task ExecuteResultAsync(ActionContext context)
+ {
+ HttpResponse response = context.HttpContext.Response;
+
+ response.Clear();
+
+ response.StatusCode = StatusCodes.Status404NotFound;
+
+ IPublishedRequest? frequest = _umbracoContext.PublishedRequest;
+ var reason = "Cannot render the page at URL '{0}'.";
+ if (frequest?.HasPublishedContent() == false)
{
- _umbracoContext = umbracoContext;
- _message = message;
+ reason = "No umbraco document matches the URL '{0}'.";
+ }
+ else if (frequest?.HasTemplate() == false)
+ {
+ reason = "No template exists to render the document at URL '{0}'.";
}
- ///
- public async Task ExecuteResultAsync(ActionContext context)
- {
- HttpResponse response = context.HttpContext.Response;
+ var viewResult = new ViewResult { ViewName = "~/umbraco/UmbracoWebsite/NotFound.cshtml" };
+ context.HttpContext.Items.Add(
+ "reason",
+ string.Format(reason, WebUtility.HtmlEncode(_umbracoContext.OriginalRequestUrl.PathAndQuery)));
+ context.HttpContext.Items.Add("message", _message);
- response.Clear();
-
- response.StatusCode = StatusCodes.Status404NotFound;
-
- IPublishedRequest? frequest = _umbracoContext.PublishedRequest;
- var reason = "Cannot render the page at URL '{0}'.";
- if (frequest?.HasPublishedContent() == false)
- {
- reason = "No umbraco document matches the URL '{0}'.";
- }
- else if (frequest?.HasTemplate() == false)
- {
- reason = "No template exists to render the document at URL '{0}'.";
- }
-
- var viewResult = new ViewResult
- {
- ViewName = "~/umbraco/UmbracoWebsite/NotFound.cshtml"
- };
- context.HttpContext.Items.Add("reason", string.Format(reason, WebUtility.HtmlEncode(_umbracoContext.OriginalRequestUrl.PathAndQuery)));
- context.HttpContext.Items.Add("message", _message);
-
- await viewResult.ExecuteResultAsync(context);
- }
+ await viewResult.ExecuteResultAsync(context);
}
}
diff --git a/src/Umbraco.Web.Common/ActionsResults/UmbracoProblemResult.cs b/src/Umbraco.Web.Common/ActionsResults/UmbracoProblemResult.cs
index 92f5d7aed7..8aa5188c3f 100644
--- a/src/Umbraco.Web.Common/ActionsResults/UmbracoProblemResult.cs
+++ b/src/Umbraco.Web.Common/ActionsResults/UmbracoProblemResult.cs
@@ -1,14 +1,11 @@
using System.Net;
using Microsoft.AspNetCore.Mvc;
-namespace Umbraco.Cms.Web.Common.ActionsResults
+namespace Umbraco.Cms.Web.Common.ActionsResults;
+
+// TODO: What is the purpose of this? Doesn't seem to add any benefit
+public class UmbracoProblemResult : ObjectResult
{
- // TODO: What is the purpose of this? Doesn't seem to add any benefit
- public class UmbracoProblemResult : ObjectResult
- {
- public UmbracoProblemResult(string message, HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError) : base(new {Message = message})
- {
- StatusCode = (int) httpStatusCode;
- }
- }
+ public UmbracoProblemResult(string message, HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError)
+ : base(new { Message = message }) => StatusCode = (int)httpStatusCode;
}
diff --git a/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs b/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs
index 3207272b66..d6996f6355 100644
--- a/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs
+++ b/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs
@@ -5,64 +5,61 @@ using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Extensions;
-namespace Umbraco.Cms.Web.Common.ActionsResults
+namespace Umbraco.Cms.Web.Common.ActionsResults;
+
+// TODO: This should probably follow the same conventions as in aspnet core and use ProblemDetails
+// and ProblemDetails factory. See https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ControllerBase.cs#L1977
+// ProblemDetails is explicitly checked for in the application model.
+// In our base class UmbracoAuthorizedApiController the logic is there to create a ProblemDetails.
+// However, to do this will require changing how angular deals with errors since the response will
+// probably be different. Would just be better to follow the aspnet patterns.
+
+///
+/// Custom result to return a validation error message with required headers
+///
+///
+/// The default status code is a 400 http response
+///
+public class ValidationErrorResult : ObjectResult
{
- // TODO: This should probably follow the same conventions as in aspnet core and use ProblemDetails
- // and ProblemDetails factory. See https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ControllerBase.cs#L1977
- // ProblemDetails is explicitly checked for in the application model.
- // In our base class UmbracoAuthorizedApiController the logic is there to create a ProblemDetails.
- // However, to do this will require changing how angular deals with errors since the response will
- // probably be different. Would just be better to follow the aspnet patterns.
+ public ValidationErrorResult(ModelStateDictionary modelState)
+ : this(new SimpleValidationModel(modelState.ToErrorDictionary()))
+ {
+ }
+
+ public ValidationErrorResult(object? value, int statusCode)
+ : base(value) => StatusCode = statusCode;
+
+ public ValidationErrorResult(object? value)
+ : this(value, StatusCodes.Status400BadRequest)
+ {
+ }
+
+ // TODO: Like here, shouldn't we use ProblemDetails?
+ public ValidationErrorResult(string errorMessage, int statusCode)
+ : base(new { Message = errorMessage }) =>
+ StatusCode = statusCode;
+
+ public ValidationErrorResult(string errorMessage)
+ : this(errorMessage, StatusCodes.Status400BadRequest)
+ {
+ }
///
- /// Custom result to return a validation error message with required headers
+ /// Typically this should not be used and just use the ValidationProblem method on the base controller class.
///
- ///
- /// The default status code is a 400 http response
- ///
- public class ValidationErrorResult : ObjectResult
+ ///
+ ///
+ public static ValidationErrorResult CreateNotificationValidationErrorResult(string errorMessage)
{
- ///
- /// Typically this should not be used and just use the ValidationProblem method on the base controller class.
- ///
- ///
- ///
- public static ValidationErrorResult CreateNotificationValidationErrorResult(string errorMessage)
- {
- var notificationModel = new SimpleNotificationModel
- {
- Message = errorMessage
- };
- notificationModel.AddErrorNotification(errorMessage, string.Empty);
- return new ValidationErrorResult(notificationModel);
- }
+ var notificationModel = new SimpleNotificationModel { Message = errorMessage };
+ notificationModel.AddErrorNotification(errorMessage, string.Empty);
+ return new ValidationErrorResult(notificationModel);
+ }
- public ValidationErrorResult(ModelStateDictionary modelState)
- : this(new SimpleValidationModel(modelState.ToErrorDictionary())) { }
-
- public ValidationErrorResult(object? value, int statusCode) : base(value)
- {
- StatusCode = statusCode;
- }
-
- public ValidationErrorResult(object? value) : this(value, StatusCodes.Status400BadRequest)
- {
- }
-
- // TODO: Like here, shouldn't we use ProblemDetails?
- public ValidationErrorResult(string errorMessage, int statusCode) : base(new { Message = errorMessage })
- {
- StatusCode = statusCode;
- }
-
- public ValidationErrorResult(string errorMessage) : this(errorMessage, StatusCodes.Status400BadRequest)
- {
- }
-
- public override void OnFormatting(ActionContext context)
- {
- base.OnFormatting(context);
- context.HttpContext.Response.Headers["X-Status-Reason"] = "Validation failed";
- }
+ public override void OnFormatting(ActionContext context)
+ {
+ base.OnFormatting(context);
+ context.HttpContext.Response.Headers["X-Status-Reason"] = "Validation failed";
}
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilder.cs b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilder.cs
index 2c817d9eb8..02d8f886cc 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilder.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilder.cs
@@ -1,21 +1,18 @@
-using System;
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+public interface IUmbracoApplicationBuilder
{
- public interface IUmbracoApplicationBuilder
- {
- ///
- /// EXPERT call to replace the middlewares that Umbraco installs by default with a completely custom pipeline.
- ///
- ///
- ///
- IUmbracoEndpointBuilder WithCustomMiddleware(Action configureUmbracoMiddleware);
+ ///
+ /// EXPERT call to replace the middlewares that Umbraco installs by default with a completely custom pipeline.
+ ///
+ ///
+ ///
+ IUmbracoEndpointBuilder WithCustomMiddleware(Action configureUmbracoMiddleware);
- ///
- /// Called to include default middleware to run umbraco.
- ///
- ///
- ///
- IUmbracoEndpointBuilder WithMiddleware(Action configureUmbracoMiddleware);
- }
+ ///
+ /// Called to include default middleware to run umbraco.
+ ///
+ ///
+ ///
+ IUmbracoEndpointBuilder WithMiddleware(Action configureUmbracoMiddleware);
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderContext.cs b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderContext.cs
index ecf62af32e..749c3feae4 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderContext.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderContext.cs
@@ -1,33 +1,30 @@
-using System;
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+///
+/// The context object used during
+///
+public interface IUmbracoApplicationBuilderContext : IUmbracoApplicationBuilderServices
{
///
- /// The context object used during
+ /// Called to include the core umbraco middleware.
///
- public interface IUmbracoApplicationBuilderContext : IUmbracoApplicationBuilderServices
- {
- ///
- /// Called to include the core umbraco middleware.
- ///
- void UseUmbracoCoreMiddleware();
+ void UseUmbracoCoreMiddleware();
- ///
- /// Manually runs the pre pipeline filters
- ///
- void RunPrePipeline();
+ ///
+ /// Manually runs the pre pipeline filters
+ ///
+ void RunPrePipeline();
- ///
- /// Manually runs the post pipeline filters
- ///
- void RunPostPipeline();
+ ///
+ /// Manually runs the post pipeline filters
+ ///
+ void RunPostPipeline();
- ///
- /// Called to include all of the default umbraco required middleware.
- ///
- ///
- /// If using this method, there is no need to use
- ///
- void RegisterDefaultRequiredMiddleware();
- }
+ ///
+ /// Called to include all of the default umbraco required middleware.
+ ///
+ ///
+ /// If using this method, there is no need to use
+ ///
+ void RegisterDefaultRequiredMiddleware();
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderServices.cs b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderServices.cs
index 5310018969..c0c76906c8 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderServices.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoApplicationBuilderServices.cs
@@ -1,16 +1,16 @@
-using System;
using Microsoft.AspNetCore.Builder;
using Umbraco.Cms.Core.Services;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
+
+///
+/// Services used during the Umbraco building phase.
+///
+public interface IUmbracoApplicationBuilderServices
{
- ///
- /// Services used during the Umbraco building phase.
- ///
- public interface IUmbracoApplicationBuilderServices
- {
- IApplicationBuilder AppBuilder { get; }
- IServiceProvider ApplicationServices { get; }
- IRuntimeState RuntimeState { get; }
- }
+ IApplicationBuilder AppBuilder { get; }
+
+ IServiceProvider ApplicationServices { get; }
+
+ IRuntimeState RuntimeState { get; }
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilder.cs b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilder.cs
index 58e0b8fec2..55b1c705bf 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilder.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilder.cs
@@ -1,13 +1,10 @@
-using System;
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+public interface IUmbracoEndpointBuilder
{
- public interface IUmbracoEndpointBuilder
- {
- ///
- /// Final call during app building to configure endpoints
- ///
- ///
- void WithEndpoints(Action configureUmbraco);
- }
+ ///
+ /// Final call during app building to configure endpoints
+ ///
+ ///
+ void WithEndpoints(Action configureUmbraco);
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilderContext.cs b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilderContext.cs
index 6122c9ef2e..db8e8a44b1 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilderContext.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoEndpointBuilderContext.cs
@@ -1,13 +1,11 @@
using Microsoft.AspNetCore.Routing;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
-{
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
- ///
- /// A builder to allow encapsulating the enabled routing features in Umbraco
- ///
- public interface IUmbracoEndpointBuilderContext : IUmbracoApplicationBuilderServices
- {
- IEndpointRouteBuilder EndpointRouteBuilder { get; }
- }
+///
+/// A builder to allow encapsulating the enabled routing features in Umbraco
+///
+public interface IUmbracoEndpointBuilderContext : IUmbracoApplicationBuilderServices
+{
+ IEndpointRouteBuilder EndpointRouteBuilder { get; }
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoPipelineFilter.cs b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoPipelineFilter.cs
index d1cf866da1..1f86dbeed7 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoPipelineFilter.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoPipelineFilter.cs
@@ -1,39 +1,39 @@
using Microsoft.AspNetCore.Builder;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
+
+///
+/// Used to modify the pipeline before and after Umbraco registers it's core
+/// middlewares.
+///
+///
+/// Mainly used for package developers.
+///
+public interface IUmbracoPipelineFilter
{
///
- /// Used to modify the pipeline before and after Umbraco registers it's core middlewares.
+ /// The name of the filter
///
///
- /// Mainly used for package developers.
+ /// This can be used by developers to see what is registered and if anything should be re-ordered, removed, etc...
///
- public interface IUmbracoPipelineFilter
- {
- ///
- /// The name of the filter
- ///
- ///
- /// This can be used by developers to see what is registered and if anything should be re-ordered, removed, etc...
- ///
- string Name { get; }
+ string Name { get; }
- ///
- /// Executes before Umbraco middlewares are registered
- ///
- ///
- void OnPrePipeline(IApplicationBuilder app);
+ ///
+ /// Executes before Umbraco middlewares are registered
+ ///
+ ///
+ void OnPrePipeline(IApplicationBuilder app);
- ///
- /// Executes after core Umbraco middlewares are registered and before any Endpoints are declared
- ///
- ///
- void OnPostPipeline(IApplicationBuilder app);
+ ///
+ /// Executes after core Umbraco middlewares are registered and before any Endpoints are declared
+ ///
+ ///
+ void OnPostPipeline(IApplicationBuilder app);
- ///
- /// Executes after just before any Umbraco endpoints are declared.
- ///
- ///
- void OnEndpoints(IApplicationBuilder app);
- }
+ ///
+ /// Executes after just before any Umbraco endpoints are declared.
+ ///
+ ///
+ void OnEndpoints(IApplicationBuilder app);
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoApplicationBuilder.cs b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoApplicationBuilder.cs
index 51af2ca22d..8bf36264eb 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoApplicationBuilder.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoApplicationBuilder.cs
@@ -1,4 +1,3 @@
-using System;
using Dazinator.Extensions.FileProviders.PrependBasePath;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -12,160 +11,163 @@ using Umbraco.Cms.Core.Services;
using Umbraco.Extensions;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
+
+///
+/// A builder used to enable middleware and endpoints required for Umbraco to operate.
+///
+///
+/// This helps to ensure that everything is registered in the correct order.
+///
+public class UmbracoApplicationBuilder : IUmbracoApplicationBuilder, IUmbracoEndpointBuilder,
+ IUmbracoApplicationBuilderContext
{
- ///
- /// A builder used to enable middleware and endpoints required for Umbraco to operate.
- ///
- ///
- /// This helps to ensure that everything is registered in the correct order.
- ///
- public class UmbracoApplicationBuilder : IUmbracoApplicationBuilder, IUmbracoEndpointBuilder, IUmbracoApplicationBuilderContext
+ private readonly IOptions _umbracoPipelineStartupOptions;
+
+ public UmbracoApplicationBuilder(IApplicationBuilder appBuilder)
{
- private readonly IOptions _umbracoPipelineStartupOptions;
+ AppBuilder = appBuilder ?? throw new ArgumentNullException(nameof(appBuilder));
+ ApplicationServices = appBuilder.ApplicationServices;
+ RuntimeState = appBuilder.ApplicationServices.GetRequiredService();
+ _umbracoPipelineStartupOptions = ApplicationServices.GetRequiredService>();
+ }
- public UmbracoApplicationBuilder(IApplicationBuilder appBuilder)
+ public IServiceProvider ApplicationServices { get; }
+
+ public IRuntimeState RuntimeState { get; }
+
+ public IApplicationBuilder AppBuilder { get; }
+
+ ///
+ public IUmbracoEndpointBuilder WithCustomMiddleware(
+ Action configureUmbracoMiddleware)
+ {
+ if (configureUmbracoMiddleware is null)
{
- AppBuilder = appBuilder ?? throw new ArgumentNullException(nameof(appBuilder));
- ApplicationServices = appBuilder.ApplicationServices;
- RuntimeState = appBuilder.ApplicationServices.GetRequiredService();
- _umbracoPipelineStartupOptions = ApplicationServices.GetRequiredService>();
+ throw new ArgumentNullException(nameof(configureUmbracoMiddleware));
}
- public IServiceProvider ApplicationServices { get; }
+ configureUmbracoMiddleware(this);
- public IRuntimeState RuntimeState { get; }
+ return this;
+ }
- public IApplicationBuilder AppBuilder { get; }
-
- ///
- public IUmbracoEndpointBuilder WithCustomMiddleware(Action configureUmbracoMiddleware)
+ ///
+ public IUmbracoEndpointBuilder WithMiddleware(Action configureUmbracoMiddleware)
+ {
+ if (configureUmbracoMiddleware is null)
{
- if (configureUmbracoMiddleware is null)
+ throw new ArgumentNullException(nameof(configureUmbracoMiddleware));
+ }
+
+ RunPrePipeline();
+
+ RegisterDefaultRequiredMiddleware();
+
+ RunPostPipeline();
+
+ configureUmbracoMiddleware(this);
+
+ return this;
+ }
+
+ ///
+ /// Registers the default required middleware to run Umbraco.
+ ///
+ public void RegisterDefaultRequiredMiddleware()
+ {
+ UseUmbracoCoreMiddleware();
+
+ // Important we handle image manipulations before the static files, otherwise the querystring is just ignored.
+ AppBuilder.UseImageSharp();
+
+ // Get media file provider and request path/URL
+ MediaFileManager mediaFileManager = AppBuilder.ApplicationServices.GetRequiredService();
+ if (mediaFileManager.FileSystem.TryCreateFileProvider(out IFileProvider? mediaFileProvider))
+ {
+ GlobalSettings globalSettings =
+ AppBuilder.ApplicationServices.GetRequiredService>().Value;
+ IHostingEnvironment? hostingEnvironment = AppBuilder.ApplicationServices.GetService();
+ var mediaRequestPath = hostingEnvironment?.ToAbsolute(globalSettings.UmbracoMediaPath);
+
+ // Configure custom file provider for media
+ IWebHostEnvironment? webHostEnvironment = AppBuilder.ApplicationServices.GetService();
+ if (webHostEnvironment is not null)
{
- throw new ArgumentNullException(nameof(configureUmbracoMiddleware));
- }
-
- configureUmbracoMiddleware(this);
-
- return this;
- }
-
- ///
- public IUmbracoEndpointBuilder WithMiddleware(Action configureUmbracoMiddleware)
- {
- if (configureUmbracoMiddleware is null)
- {
- throw new ArgumentNullException(nameof(configureUmbracoMiddleware));
- }
-
- RunPrePipeline();
-
- RegisterDefaultRequiredMiddleware();
-
- RunPostPipeline();
-
- configureUmbracoMiddleware(this);
-
- return this;
- }
-
- ///
- public void WithEndpoints(Action configureUmbraco)
- {
- IOptions startupOptions = ApplicationServices.GetRequiredService>();
- RunPreEndpointsPipeline();
-
- AppBuilder.UseEndpoints(endpoints =>
- {
- var umbAppBuilder = (IUmbracoEndpointBuilderContext)ActivatorUtilities.CreateInstance(
- ApplicationServices,
- new object[] { AppBuilder, endpoints });
- configureUmbraco(umbAppBuilder);
- });
- }
-
- ///
- /// Registers the default required middleware to run Umbraco.
- ///
- public void RegisterDefaultRequiredMiddleware()
- {
- UseUmbracoCoreMiddleware();
-
- // Important we handle image manipulations before the static files, otherwise the querystring is just ignored.
- AppBuilder.UseImageSharp();
-
- // Get media file provider and request path/URL
- var mediaFileManager = AppBuilder.ApplicationServices.GetRequiredService();
- if (mediaFileManager.FileSystem.TryCreateFileProvider(out IFileProvider? mediaFileProvider))
- {
- GlobalSettings globalSettings = AppBuilder.ApplicationServices.GetRequiredService>().Value;
- IHostingEnvironment? hostingEnvironment = AppBuilder.ApplicationServices.GetService();
- string? mediaRequestPath = hostingEnvironment?.ToAbsolute(globalSettings.UmbracoMediaPath);
-
- // Configure custom file provider for media
- IWebHostEnvironment? webHostEnvironment = AppBuilder.ApplicationServices.GetService();
- if (webHostEnvironment is not null)
- {
- webHostEnvironment.WebRootFileProvider = webHostEnvironment.WebRootFileProvider.ConcatComposite(new PrependBasePathFileProvider(mediaRequestPath, mediaFileProvider));
- }
- }
-
- AppBuilder.UseStaticFiles();
-
- AppBuilder.UseUmbracoPluginsStaticFiles();
-
- // UseRouting adds endpoint routing middleware, this means that middlewares registered after this one
- // will execute after endpoint routing. The ordering of everything is quite important here, see
- // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0
- // where we need to have UseAuthentication and UseAuthorization proceeding this call but before
- // endpoints are defined.
- AppBuilder.UseRouting();
- AppBuilder.UseAuthentication();
- AppBuilder.UseAuthorization();
-
- // This must come after auth because the culture is based on the auth'd user
- AppBuilder.UseRequestLocalization();
-
- // Must be called after UseRouting and before UseEndpoints
- AppBuilder.UseSession();
-
- // DO NOT PUT ANY UseEndpoints declarations here!! Those must all come very last in the pipeline,
- // endpoints are terminating middleware. All of our endpoints are declared in ext of IUmbracoApplicationBuilder
- }
-
- public void UseUmbracoCoreMiddleware()
- {
- AppBuilder.UseUmbracoCore();
- AppBuilder.UseUmbracoRequestLogging();
-
- // We need to add this before UseRouting so that the UmbracoContext and other middlewares are executed
- // before endpoint routing middleware.
- AppBuilder.UseUmbracoRouting();
- }
-
- public void RunPrePipeline()
- {
- foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
- {
- filter.OnPrePipeline(AppBuilder);
+ webHostEnvironment.WebRootFileProvider =
+ webHostEnvironment.WebRootFileProvider.ConcatComposite(
+ new PrependBasePathFileProvider(mediaRequestPath, mediaFileProvider));
}
}
- public void RunPostPipeline()
- {
- foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
- {
- filter.OnPostPipeline(AppBuilder);
- }
- }
+ AppBuilder.UseStaticFiles();
- private void RunPreEndpointsPipeline()
+ AppBuilder.UseUmbracoPluginsStaticFiles();
+
+ // UseRouting adds endpoint routing middleware, this means that middlewares registered after this one
+ // will execute after endpoint routing. The ordering of everything is quite important here, see
+ // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0
+ // where we need to have UseAuthentication and UseAuthorization proceeding this call but before
+ // endpoints are defined.
+ AppBuilder.UseRouting();
+ AppBuilder.UseAuthentication();
+ AppBuilder.UseAuthorization();
+
+ // This must come after auth because the culture is based on the auth'd user
+ AppBuilder.UseRequestLocalization();
+
+ // Must be called after UseRouting and before UseEndpoints
+ AppBuilder.UseSession();
+
+ // DO NOT PUT ANY UseEndpoints declarations here!! Those must all come very last in the pipeline,
+ // endpoints are terminating middleware. All of our endpoints are declared in ext of IUmbracoApplicationBuilder
+ }
+
+ public void UseUmbracoCoreMiddleware()
+ {
+ AppBuilder.UseUmbracoCore();
+ AppBuilder.UseUmbracoRequestLogging();
+
+ // We need to add this before UseRouting so that the UmbracoContext and other middlewares are executed
+ // before endpoint routing middleware.
+ AppBuilder.UseUmbracoRouting();
+ }
+
+ public void RunPrePipeline()
+ {
+ foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
{
- foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
- {
- filter.OnEndpoints(AppBuilder);
- }
+ filter.OnPrePipeline(AppBuilder);
+ }
+ }
+
+ public void RunPostPipeline()
+ {
+ foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
+ {
+ filter.OnPostPipeline(AppBuilder);
+ }
+ }
+
+ ///
+ public void WithEndpoints(Action configureUmbraco)
+ {
+ RunPreEndpointsPipeline();
+
+ AppBuilder.UseEndpoints(endpoints =>
+ {
+ var umbAppBuilder =
+ (IUmbracoEndpointBuilderContext)ActivatorUtilities.CreateInstance(
+ ApplicationServices, AppBuilder, endpoints);
+ configureUmbraco(umbAppBuilder);
+ });
+ }
+
+ private void RunPreEndpointsPipeline()
+ {
+ foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
+ {
+ filter.OnEndpoints(AppBuilder);
}
}
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoEndpointBuilder.cs b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoEndpointBuilder.cs
index 86e8f3e957..fa75ed116d 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoEndpointBuilder.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoEndpointBuilder.cs
@@ -1,26 +1,27 @@
-using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Umbraco.Cms.Core.Services;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
-{
- ///
- /// A builder to allow encapsulating the enabled endpoints in Umbraco
- ///
- internal class UmbracoEndpointBuilder : IUmbracoEndpointBuilderContext
- {
- public UmbracoEndpointBuilder(IServiceProvider services, IRuntimeState runtimeState, IApplicationBuilder appBuilder, IEndpointRouteBuilder endpointRouteBuilder)
- {
- ApplicationServices = services;
- EndpointRouteBuilder = endpointRouteBuilder;
- RuntimeState = runtimeState;
- AppBuilder = appBuilder;
- }
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
- public IServiceProvider ApplicationServices { get; }
- public IEndpointRouteBuilder EndpointRouteBuilder { get; }
- public IRuntimeState RuntimeState { get; }
- public IApplicationBuilder AppBuilder { get; }
+///
+/// A builder to allow encapsulating the enabled endpoints in Umbraco
+///
+internal class UmbracoEndpointBuilder : IUmbracoEndpointBuilderContext
+{
+ public UmbracoEndpointBuilder(IServiceProvider services, IRuntimeState runtimeState, IApplicationBuilder appBuilder, IEndpointRouteBuilder endpointRouteBuilder)
+ {
+ ApplicationServices = services;
+ EndpointRouteBuilder = endpointRouteBuilder;
+ RuntimeState = runtimeState;
+ AppBuilder = appBuilder;
}
+
+ public IServiceProvider ApplicationServices { get; }
+
+ public IEndpointRouteBuilder EndpointRouteBuilder { get; }
+
+ public IRuntimeState RuntimeState { get; }
+
+ public IApplicationBuilder AppBuilder { get; }
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineFilter.cs b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineFilter.cs
index 25d006634a..aa11bc6bd9 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineFilter.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineFilter.cs
@@ -1,37 +1,44 @@
-using System;
using Microsoft.AspNetCore.Builder;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
+
+///
+/// Used to modify the pipeline before and after Umbraco registers it's core
+/// middlewares.
+///
+///
+/// Mainly used for package developers.
+///
+public class UmbracoPipelineFilter : IUmbracoPipelineFilter
{
- ///
- /// Used to modify the pipeline before and after Umbraco registers it's core middlewares.
- ///
- ///
- /// Mainly used for package developers.
- ///
- public class UmbracoPipelineFilter : IUmbracoPipelineFilter
+ public UmbracoPipelineFilter(string name)
+ : this(name, null, null, null)
{
- public UmbracoPipelineFilter(string name) : this(name, null, null, null) { }
-
- public UmbracoPipelineFilter(
- string name,
- Action? prePipeline,
- Action? postPipeline,
- Action? endpointCallback)
- {
- Name = name ?? throw new ArgumentNullException(nameof(name));
- PrePipeline = prePipeline;
- PostPipeline = postPipeline;
- Endpoints = endpointCallback;
- }
-
- public Action? PrePipeline { get; set; }
- public Action? PostPipeline { get; set; }
- public Action? Endpoints { get; set; }
- public string Name { get; }
-
- public void OnPrePipeline(IApplicationBuilder app) => PrePipeline?.Invoke(app);
- public void OnPostPipeline(IApplicationBuilder app) => PostPipeline?.Invoke(app);
- public void OnEndpoints(IApplicationBuilder app) => Endpoints?.Invoke(app);
}
+
+ public UmbracoPipelineFilter(
+ string name,
+ Action? prePipeline,
+ Action? postPipeline,
+ Action? endpointCallback)
+ {
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ PrePipeline = prePipeline;
+ PostPipeline = postPipeline;
+ Endpoints = endpointCallback;
+ }
+
+ public Action? PrePipeline { get; set; }
+
+ public Action? PostPipeline { get; set; }
+
+ public Action? Endpoints { get; set; }
+
+ public string Name { get; }
+
+ public void OnPrePipeline(IApplicationBuilder app) => PrePipeline?.Invoke(app);
+
+ public void OnPostPipeline(IApplicationBuilder app) => PostPipeline?.Invoke(app);
+
+ public void OnEndpoints(IApplicationBuilder app) => Endpoints?.Invoke(app);
}
diff --git a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineOptions.cs b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineOptions.cs
index 8cf2b4144a..48c5cd9408 100644
--- a/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineOptions.cs
+++ b/src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineOptions.cs
@@ -1,22 +1,21 @@
-using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
-namespace Umbraco.Cms.Web.Common.ApplicationBuilder
+namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
+
+///
+/// Options to allow modifying the pipeline before and after Umbraco registers it's
+/// core middlewares.
+///
+public class UmbracoPipelineOptions
{
///
- /// Options to allow modifying the pipeline before and after Umbraco registers it's core middlewares.
+ /// Returns a mutable list of all registered startup filters
///
- public class UmbracoPipelineOptions
- {
- ///
- /// Returns a mutable list of all registered startup filters
- ///
- public IList PipelineFilters { get; } = new List();
+ public IList PipelineFilters { get; } = new List();
- ///
- /// Adds a filter to the list
- ///
- ///
- public void AddFilter(IUmbracoPipelineFilter filter) => PipelineFilters.Add(filter);
- }
+ ///
+ /// Adds a filter to the list
+ ///
+ ///
+ public void AddFilter(IUmbracoPipelineFilter filter) => PipelineFilters.Add(filter);
}
diff --git a/src/Umbraco.Web.Common/ApplicationModels/BackOfficeApplicationModelProvider.cs b/src/Umbraco.Web.Common/ApplicationModels/BackOfficeApplicationModelProvider.cs
index 146edb19e9..a4b926ac93 100644
--- a/src/Umbraco.Web.Common/ApplicationModels/BackOfficeApplicationModelProvider.cs
+++ b/src/Umbraco.Web.Common/ApplicationModels/BackOfficeApplicationModelProvider.cs
@@ -1,56 +1,51 @@
-using System.Collections.Generic;
-using System.Linq;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
-using Microsoft.AspNetCore.Mvc.ModelBinding;
using Umbraco.Cms.Web.Common.Attributes;
-namespace Umbraco.Cms.Web.Common.ApplicationModels
+namespace Umbraco.Cms.Web.Common.ApplicationModels;
+
+// TODO: This should just exist in the back office project
+
+///
+/// An application model provider for all Umbraco Back Office controllers
+///
+public class BackOfficeApplicationModelProvider : IApplicationModelProvider
{
-
- // TODO: This should just exist in the back office project
-
- ///
- /// An application model provider for all Umbraco Back Office controllers
- ///
- public class BackOfficeApplicationModelProvider : IApplicationModelProvider
+ private readonly List _actionModelConventions = new()
{
- private readonly List _actionModelConventions = new List()
- {
- new BackOfficeIdentityCultureConvention()
- };
+ new BackOfficeIdentityCultureConvention(),
+ };
- ///
- ///
- /// Will execute after
- ///
- public int Order => 0;
+ ///
+ ///
+ /// Will execute after
+ ///
+ public int Order => 0;
- ///
- public void OnProvidersExecuted(ApplicationModelProviderContext context)
- {
- }
+ ///
+ public void OnProvidersExecuted(ApplicationModelProviderContext context)
+ {
+ }
- ///
- public void OnProvidersExecuting(ApplicationModelProviderContext context)
+ ///
+ public void OnProvidersExecuting(ApplicationModelProviderContext context)
+ {
+ foreach (ControllerModel controller in context.Result.Controllers)
{
- foreach (ControllerModel controller in context.Result.Controllers)
+ if (!IsBackOfficeController(controller))
{
- if (!IsBackOfficeController(controller))
- {
- continue;
- }
+ continue;
+ }
- foreach (ActionModel action in controller.Actions)
+ foreach (ActionModel action in controller.Actions)
+ {
+ foreach (IActionModelConvention convention in _actionModelConventions)
{
- foreach (IActionModelConvention convention in _actionModelConventions)
- {
- convention.Apply(action);
- }
+ convention.Apply(action);
}
}
}
-
- private bool IsBackOfficeController(ControllerModel controller)
- => controller.Attributes.OfType().Any();
}
+
+ private bool IsBackOfficeController(ControllerModel controller)
+ => controller.Attributes.OfType().Any();
}
diff --git a/src/Umbraco.Web.Common/ApplicationModels/BackOfficeIdentityCultureConvention.cs b/src/Umbraco.Web.Common/ApplicationModels/BackOfficeIdentityCultureConvention.cs
index 8414662816..ffc2d33278 100644
--- a/src/Umbraco.Web.Common/ApplicationModels/BackOfficeIdentityCultureConvention.cs
+++ b/src/Umbraco.Web.Common/ApplicationModels/BackOfficeIdentityCultureConvention.cs
@@ -1,14 +1,11 @@
-using Microsoft.AspNetCore.Mvc.ApplicationModels;
+using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Umbraco.Cms.Web.Common.Filters;
-namespace Umbraco.Cms.Web.Common.ApplicationModels
+namespace Umbraco.Cms.Web.Common.ApplicationModels;
+
+// TODO: This should just exist in the back office project
+public class BackOfficeIdentityCultureConvention : IActionModelConvention
{
-
- // TODO: This should just exist in the back office project
-
- public class BackOfficeIdentityCultureConvention : IActionModelConvention
- {
- ///
- public void Apply(ActionModel action) => action.Filters.Add(new BackOfficeCultureFilter());
- }
+ ///
+ public void Apply(ActionModel action) => action.Filters.Add(new BackOfficeCultureFilter());
}
diff --git a/src/Umbraco.Web.Common/ApplicationModels/UmbracoApiBehaviorApplicationModelProvider.cs b/src/Umbraco.Web.Common/ApplicationModels/UmbracoApiBehaviorApplicationModelProvider.cs
index df0584386b..d2165a63ee 100644
--- a/src/Umbraco.Web.Common/ApplicationModels/UmbracoApiBehaviorApplicationModelProvider.cs
+++ b/src/Umbraco.Web.Common/ApplicationModels/UmbracoApiBehaviorApplicationModelProvider.cs
@@ -1,90 +1,86 @@
-using System.Collections.Generic;
-using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Umbraco.Cms.Web.Common.Attributes;
-namespace Umbraco.Cms.Web.Common.ApplicationModels
+namespace Umbraco.Cms.Web.Common.ApplicationModels;
+
+///
+/// An application model provider for Umbraco API controllers to behave like WebApi controllers
+///
+///
+///
+/// Conventions will be applied to controllers attributed with
+///
+///
+/// This is nearly a copy of aspnetcore's ApiBehaviorApplicationModelProvider which supplies a convention for the
+/// [ApiController] attribute, however that convention is too strict for our purposes so we will have our own.
+/// Uses UmbracoJsonModelBinder for complex parameters and those with BindingSource of Body, but leaves the rest
+/// alone see GH #11554
+///
+///
+/// See https://shazwazza.com/post/custom-body-model-binding-per-controller-in-asp-net-core/
+/// and https://github.com/dotnet/aspnetcore/issues/21724
+///
+///
+public class UmbracoApiBehaviorApplicationModelProvider : IApplicationModelProvider
{
+ private readonly List _actionModelConventions;
///
- /// An application model provider for Umbraco API controllers to behave like WebApi controllers
+ /// Initializes a new instance of the class.
///
- ///
- ///
- /// Conventions will be applied to controllers attributed with
- ///
- ///
- /// This is nearly a copy of aspnetcore's ApiBehaviorApplicationModelProvider which supplies a convention for the
- /// [ApiController] attribute, however that convention is too strict for our purposes so we will have our own.
- /// Uses UmbracoJsonModelBinder for complex parameters and those with BindingSource of Body, but leaves the rest alone see GH #11554
- ///
- ///
- /// See https://shazwazza.com/post/custom-body-model-binding-per-controller-in-asp-net-core/
- /// and https://github.com/dotnet/aspnetcore/issues/21724
- ///
- ///
- public class UmbracoApiBehaviorApplicationModelProvider : IApplicationModelProvider
+ public UmbracoApiBehaviorApplicationModelProvider(IModelMetadataProvider modelMetadataProvider)
{
- private readonly List _actionModelConventions;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public UmbracoApiBehaviorApplicationModelProvider(IModelMetadataProvider modelMetadataProvider)
+ // see see https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-3.1#apicontroller-attribute
+ // for what these things actually do
+ // NOTE: we don't have attribute routing requirements and we cannot use ApiVisibilityConvention without attribute routing
+ _actionModelConventions = new List
{
- // see see https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-3.1#apicontroller-attribute
- // for what these things actually do
- // NOTE: we don't have attribute routing requirements and we cannot use ApiVisibilityConvention without attribute routing
+ new ClientErrorResultFilterConvention(), // Ensures the responses without any body is converted into a simple json object with info instead of a string like "Status Code: 404; Not Found"
+ new ConsumesConstraintForFormFileParameterConvention(), // If an controller accepts files, it must accept multipart/form-data.
- _actionModelConventions = new List()
+ // This ensures that all parameters of type BindingSource.Body and those of complex type are bound
+ // using our own UmbracoJsonModelBinder
+ new UmbracoJsonModelBinderConvention(modelMetadataProvider),
+ };
+
+ Type defaultErrorType = typeof(ProblemDetails);
+ var defaultErrorTypeAttribute = new ProducesErrorResponseTypeAttribute(defaultErrorType);
+ _actionModelConventions.Add(new ApiConventionApplicationModelConvention(defaultErrorTypeAttribute));
+ }
+
+ ///
+ ///
+ /// Will execute after
+ ///
+ public int Order => 0;
+
+ ///
+ public void OnProvidersExecuted(ApplicationModelProviderContext context)
+ {
+ }
+
+ ///
+ public void OnProvidersExecuting(ApplicationModelProviderContext context)
+ {
+ foreach (ControllerModel controller in context.Result.Controllers)
+ {
+ if (!IsUmbracoApiController(controller))
{
- new ClientErrorResultFilterConvention(), // Ensures the responses without any body is converted into a simple json object with info instead of a string like "Status Code: 404; Not Found"
- new ConsumesConstraintForFormFileParameterConvention(), // If an controller accepts files, it must accept multipart/form-data.
+ continue;
+ }
- // This ensures that all parameters of type BindingSource.Body and those of complex type are bound
- // using our own UmbracoJsonModelBinder
- new UmbracoJsonModelBinderConvention(modelMetadataProvider)
- };
-
- var defaultErrorType = typeof(ProblemDetails);
- var defaultErrorTypeAttribute = new ProducesErrorResponseTypeAttribute(defaultErrorType);
- _actionModelConventions.Add(new ApiConventionApplicationModelConvention(defaultErrorTypeAttribute));
- }
-
- ///
- ///
- /// Will execute after
- ///
- public int Order => 0;
-
- ///
- public void OnProvidersExecuted(ApplicationModelProviderContext context)
- {
- }
-
- ///
- public void OnProvidersExecuting(ApplicationModelProviderContext context)
- {
- foreach (ControllerModel controller in context.Result.Controllers)
+ foreach (ActionModel action in controller.Actions)
{
- if (!IsUmbracoApiController(controller))
+ foreach (IActionModelConvention convention in _actionModelConventions)
{
- continue;
- }
-
- foreach (ActionModel action in controller.Actions)
- {
- foreach (IActionModelConvention convention in _actionModelConventions)
- {
- convention.Apply(action);
- }
+ convention.Apply(action);
}
}
}
-
- private static bool IsUmbracoApiController(ICommonModel controller)
- => controller.Attributes.OfType().Any();
}
+
+ private static bool IsUmbracoApiController(ICommonModel controller)
+ => controller.Attributes.OfType().Any();
}
diff --git a/src/Umbraco.Web.Common/ApplicationModels/UmbracoJsonModelBinderConvention.cs b/src/Umbraco.Web.Common/ApplicationModels/UmbracoJsonModelBinderConvention.cs
index 2eff08d54d..236cb39ce3 100644
--- a/src/Umbraco.Web.Common/ApplicationModels/UmbracoJsonModelBinderConvention.cs
+++ b/src/Umbraco.Web.Common/ApplicationModels/UmbracoJsonModelBinderConvention.cs
@@ -4,58 +4,55 @@ using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Web.Common.DependencyInjection;
using Umbraco.Cms.Web.Common.ModelBinders;
-namespace Umbraco.Cms.Web.Common.ApplicationModels
+namespace Umbraco.Cms.Web.Common.ApplicationModels;
+
+///
+/// Applies the body model binder to any complex parameter and those with a
+/// binding source of type
+///
+public class UmbracoJsonModelBinderConvention : IActionModelConvention
{
- ///
- /// Applies the body model binder to any complex parameter and those with a
- /// binding source of type
- ///
- public class UmbracoJsonModelBinderConvention : IActionModelConvention
+ private readonly IModelMetadataProvider _modelMetadataProvider;
+
+ public UmbracoJsonModelBinderConvention()
+ : this(StaticServiceProvider.Instance.GetRequiredService())
{
- private readonly IModelMetadataProvider _modelMetadataProvider;
+ }
- public UmbracoJsonModelBinderConvention()
- : this(StaticServiceProvider.Instance.GetRequiredService())
- {
- }
+ public UmbracoJsonModelBinderConvention(IModelMetadataProvider modelMetadataProvider) =>
+ _modelMetadataProvider = modelMetadataProvider;
- public UmbracoJsonModelBinderConvention(IModelMetadataProvider modelMetadataProvider)
+ ///
+ public void Apply(ActionModel action)
+ {
+ foreach (ParameterModel p in action.Parameters)
{
- _modelMetadataProvider = modelMetadataProvider;
- }
-
- ///
- public void Apply(ActionModel action)
- {
- foreach (ParameterModel p in action.Parameters)
+ if (p.BindingInfo == null)
{
- if (p.BindingInfo == null)
+ if (IsComplexTypeParameter(p))
{
- if (IsComplexTypeParameter(p))
+ p.BindingInfo = new BindingInfo
{
- p.BindingInfo = new BindingInfo
- {
- BindingSource = BindingSource.Body,
- BinderType = typeof(UmbracoJsonModelBinder)
- };
- }
-
- continue;
+ BindingSource = BindingSource.Body,
+ BinderType = typeof(UmbracoJsonModelBinder),
+ };
}
- if (p.BindingInfo.BindingSource == BindingSource.Body)
- {
- p.BindingInfo.BinderType = typeof(UmbracoJsonModelBinder);
- }
+ continue;
+ }
+
+ if (p.BindingInfo.BindingSource == BindingSource.Body)
+ {
+ p.BindingInfo.BinderType = typeof(UmbracoJsonModelBinder);
}
}
+ }
- private bool IsComplexTypeParameter(ParameterModel parameter)
- {
- // No need for information from attributes on the parameter. Just use its type.
- ModelMetadata metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterInfo.ParameterType);
+ private bool IsComplexTypeParameter(ParameterModel parameter)
+ {
+ // No need for information from attributes on the parameter. Just use its type.
+ ModelMetadata metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterInfo.ParameterType);
- return metadata.IsComplexType;
- }
+ return metadata.IsComplexType;
}
}
diff --git a/src/Umbraco.Web.Common/ApplicationModels/VirtualPageApplicationModelProvider.cs b/src/Umbraco.Web.Common/ApplicationModels/VirtualPageApplicationModelProvider.cs
index 7697b9841a..5fb52d8fd0 100644
--- a/src/Umbraco.Web.Common/ApplicationModels/VirtualPageApplicationModelProvider.cs
+++ b/src/Umbraco.Web.Common/ApplicationModels/VirtualPageApplicationModelProvider.cs
@@ -1,61 +1,58 @@
-using System.Collections.Generic;
-using System.Linq;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Web.Common.Controllers;
using Umbraco.Extensions;
-namespace Umbraco.Cms.Web.Common.ApplicationModels
+namespace Umbraco.Cms.Web.Common.ApplicationModels;
+
+///
+/// Applies the to any action on a controller that is
+///
+///
+public class VirtualPageApplicationModelProvider : IApplicationModelProvider
{
+ private readonly List _actionModelConventions = new() { new VirtualPageConvention() };
+
+ ///
///
- /// Applies the to any action on a controller that is
+ /// Will execute after
///
- public class VirtualPageApplicationModelProvider : IApplicationModelProvider
+ public int Order => 0;
+
+ ///
+ public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
- private readonly List _actionModelConventions = new List()
+ }
+
+ ///
+ public void OnProvidersExecuting(ApplicationModelProviderContext context)
+ {
+ foreach (ControllerModel controller in context.Result.Controllers)
{
- new VirtualPageConvention()
- };
-
- ///
- ///
- /// Will execute after
- ///
- public int Order => 0;
-
- ///
- public void OnProvidersExecuted(ApplicationModelProviderContext context) { }
-
- ///
- public void OnProvidersExecuting(ApplicationModelProviderContext context)
- {
- foreach (ControllerModel controller in context.Result.Controllers)
+ if (!IsVirtualPageController(controller))
{
- if (!IsVirtualPageController(controller))
- {
- continue;
- }
+ continue;
+ }
- foreach (ActionModel action in controller.Actions.ToList())
+ foreach (ActionModel action in controller.Actions.ToList())
+ {
+ if (action.ActionName == nameof(IVirtualPageController.FindContent)
+ && action.ActionMethod.ReturnType == typeof(IPublishedContent))
{
- if (action.ActionName == nameof(IVirtualPageController.FindContent)
- && action.ActionMethod.ReturnType == typeof(IPublishedContent))
+ // this is not an action, it's just the implementation of IVirtualPageController
+ controller.Actions.Remove(action);
+ }
+ else
+ {
+ foreach (IActionModelConvention convention in _actionModelConventions)
{
- // this is not an action, it's just the implementation of IVirtualPageController
- controller.Actions.Remove(action);
- }
- else
- {
- foreach (IActionModelConvention convention in _actionModelConventions)
- {
- convention.Apply(action);
- }
+ convention.Apply(action);
}
}
}
}
-
- private bool IsVirtualPageController(ControllerModel controller)
- => controller.ControllerType.Implements();
}
+
+ private bool IsVirtualPageController(ControllerModel controller)
+ => controller.ControllerType.Implements();
}
diff --git a/src/Umbraco.Web.Common/ApplicationModels/VirtualPageConvention.cs b/src/Umbraco.Web.Common/ApplicationModels/VirtualPageConvention.cs
index 66b68c7a85..76e1c8f980 100644
--- a/src/Umbraco.Web.Common/ApplicationModels/VirtualPageConvention.cs
+++ b/src/Umbraco.Web.Common/ApplicationModels/VirtualPageConvention.cs
@@ -1,14 +1,13 @@
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Umbraco.Cms.Web.Common.Filters;
-namespace Umbraco.Cms.Web.Common.ApplicationModels
+namespace Umbraco.Cms.Web.Common.ApplicationModels;
+
+///
+/// Adds the as a convention
+///
+public class VirtualPageConvention : IActionModelConvention
{
- ///
- /// Adds the as a convention
- ///
- public class VirtualPageConvention : IActionModelConvention
- {
- ///
- public void Apply(ActionModel action) => action.Filters.Add(new UmbracoVirtualPageFilterAttribute());
- }
+ ///
+ public void Apply(ActionModel action) => action.Filters.Add(new UmbracoVirtualPageFilterAttribute());
}
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
index ff431966ce..65c03ffafc 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreApplicationShutdownRegistry.cs
@@ -1,54 +1,51 @@
-using System;
using System.Collections.Concurrent;
-using System.Threading;
using Microsoft.Extensions.Hosting;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Hosting;
-namespace Umbraco.Cms.Web.Common.AspNetCore
+namespace Umbraco.Cms.Web.Common.AspNetCore;
+
+public class AspNetCoreApplicationShutdownRegistry : IApplicationShutdownRegistry
{
- public class AspNetCoreApplicationShutdownRegistry : IApplicationShutdownRegistry
+ private readonly IHostApplicationLifetime _hostApplicationLifetime;
+
+ private readonly ConcurrentDictionary _registeredObjects = new();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public AspNetCoreApplicationShutdownRegistry(IHostApplicationLifetime hostApplicationLifetime)
+ => _hostApplicationLifetime = hostApplicationLifetime;
+
+ public void RegisterObject(IRegisteredObject registeredObject)
{
- private readonly IHostApplicationLifetime _hostApplicationLifetime;
- private readonly ConcurrentDictionary _registeredObjects =
- new ConcurrentDictionary();
-
- ///
- /// Initializes a new instance of the class.
- ///
- public AspNetCoreApplicationShutdownRegistry(IHostApplicationLifetime hostApplicationLifetime)
- => _hostApplicationLifetime = hostApplicationLifetime;
-
- public void RegisterObject(IRegisteredObject registeredObject)
+ var wrapped = new RegisteredObjectWrapper(registeredObject);
+ if (!_registeredObjects.TryAdd(registeredObject, wrapped))
{
- var wrapped = new RegisteredObjectWrapper(registeredObject);
- if (!_registeredObjects.TryAdd(registeredObject, wrapped))
- {
- throw new InvalidOperationException("Could not register object");
- }
-
- var cancellationTokenRegistration = _hostApplicationLifetime.ApplicationStopping.Register(() => wrapped.Stop(true));
- wrapped.CancellationTokenRegistration = cancellationTokenRegistration;
+ throw new InvalidOperationException("Could not register object");
}
- public void UnregisterObject(IRegisteredObject registeredObject)
+ CancellationTokenRegistration cancellationTokenRegistration =
+ _hostApplicationLifetime.ApplicationStopping.Register(() => wrapped.Stop(true));
+ wrapped.CancellationTokenRegistration = cancellationTokenRegistration;
+ }
+
+ public void UnregisterObject(IRegisteredObject registeredObject)
+ {
+ if (_registeredObjects.TryGetValue(registeredObject, out RegisteredObjectWrapper? wrapped))
{
- if (_registeredObjects.TryGetValue(registeredObject, out var wrapped))
- {
- wrapped.CancellationTokenRegistration.Unregister();
- }
- }
-
-
- private class RegisteredObjectWrapper
- {
- private readonly IRegisteredObject _inner;
-
- public RegisteredObjectWrapper(IRegisteredObject inner) => _inner = inner;
-
- public CancellationTokenRegistration CancellationTokenRegistration { get; set; }
-
- public void Stop(bool immediate) => _inner.Stop(immediate);
+ wrapped.CancellationTokenRegistration.Unregister();
}
}
+
+ private class RegisteredObjectWrapper
+ {
+ private readonly IRegisteredObject _inner;
+
+ public RegisteredObjectWrapper(IRegisteredObject inner) => _inner = inner;
+
+ public CancellationTokenRegistration CancellationTokenRegistration { get; set; }
+
+ public void Stop(bool immediate) => _inner.Stop(immediate);
+ }
}
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreBackOfficeInfo.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreBackOfficeInfo.cs
index 7107ab3331..d0f8f7b02b 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreBackOfficeInfo.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreBackOfficeInfo.cs
@@ -5,34 +5,39 @@ using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Routing;
using static Umbraco.Cms.Core.Constants;
-namespace Umbraco.Cms.Web.Common.AspNetCore
+namespace Umbraco.Cms.Web.Common.AspNetCore;
+
+public class AspNetCoreBackOfficeInfo : IBackOfficeInfo
{
- public class AspNetCoreBackOfficeInfo : IBackOfficeInfo
+ private readonly IOptionsMonitor _globalSettings;
+ private readonly IHostingEnvironment _hostingEnvironment;
+ private string? _getAbsoluteUrl;
+
+ public AspNetCoreBackOfficeInfo(
+ IOptionsMonitor globalSettings,
+ IHostingEnvironment hostingEnviroment)
{
- private readonly IOptionsMonitor _globalSettings;
- private readonly IHostingEnvironment _hostingEnvironment;
- private string? _getAbsoluteUrl;
- public AspNetCoreBackOfficeInfo(IOptionsMonitor globalSettings, IHostingEnvironment hostingEnviroment)
- {
- _globalSettings = globalSettings;
- _hostingEnvironment = hostingEnviroment;
+ _globalSettings = globalSettings;
+ _hostingEnvironment = hostingEnviroment;
+ }
- }
-
- public string GetAbsoluteUrl
+ public string GetAbsoluteUrl
+ {
+ get
{
- get
+ if (_getAbsoluteUrl is null)
{
- if (_getAbsoluteUrl is null)
+ if (_hostingEnvironment.ApplicationMainUrl is null)
{
- if(_hostingEnvironment.ApplicationMainUrl is null)
- {
- return "";
- }
- _getAbsoluteUrl = WebPath.Combine(_hostingEnvironment.ApplicationMainUrl.ToString(), _globalSettings.CurrentValue.UmbracoPath.TrimStart(CharArrays.TildeForwardSlash));
+ return string.Empty;
}
- return _getAbsoluteUrl;
+
+ _getAbsoluteUrl = WebPath.Combine(
+ _hostingEnvironment.ApplicationMainUrl.ToString(),
+ _globalSettings.CurrentValue.UmbracoPath.TrimStart(CharArrays.TildeForwardSlash));
}
+
+ return _getAbsoluteUrl;
}
}
}
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs
index 478e8aa13d..2f5ff585ed 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs
@@ -1,49 +1,34 @@
-using System;
using Microsoft.AspNetCore.Http;
using Umbraco.Cms.Core.Web;
-namespace Umbraco.Cms.Web.Common.AspNetCore
+namespace Umbraco.Cms.Web.Common.AspNetCore;
+
+public class AspNetCoreCookieManager : ICookieManager
{
- public class AspNetCoreCookieManager : ICookieManager
+ private readonly IHttpContextAccessor _httpContextAccessor;
+
+ public AspNetCoreCookieManager(IHttpContextAccessor httpContextAccessor) =>
+ _httpContextAccessor = httpContextAccessor;
+
+ public void ExpireCookie(string cookieName)
{
- private readonly IHttpContextAccessor _httpContextAccessor;
+ HttpContext? httpContext = _httpContextAccessor.HttpContext;
- public AspNetCoreCookieManager(IHttpContextAccessor httpContextAccessor)
+ if (httpContext is null)
{
- _httpContextAccessor = httpContextAccessor;
+ return;
}
- public void ExpireCookie(string cookieName)
- {
- var httpContext = _httpContextAccessor.HttpContext;
-
- if (httpContext is null) return;
-
- var cookieValue = httpContext.Request.Cookies[cookieName];
-
- httpContext.Response.Cookies.Append(cookieName, cookieValue ?? string.Empty, new CookieOptions()
- {
- Expires = DateTime.Now.AddYears(-1)
- });
- }
-
- public string? GetCookieValue(string cookieName)
- {
- return _httpContextAccessor.HttpContext?.Request.Cookies[cookieName];
- }
-
- public void SetCookieValue(string cookieName, string value)
- {
- _httpContextAccessor.HttpContext?.Response.Cookies.Append(cookieName, value, new CookieOptions()
- {
-
- });
- }
-
- public bool HasCookie(string cookieName)
- {
- return !(GetCookieValue(cookieName) is null);
- }
+ var cookieValue = httpContext.Request.Cookies[cookieName];
+ httpContext.Response.Cookies.Append(cookieName, cookieValue ?? string.Empty,
+ new CookieOptions { Expires = DateTime.Now.AddYears(-1) });
}
+
+ public string? GetCookieValue(string cookieName) => _httpContextAccessor.HttpContext?.Request.Cookies[cookieName];
+
+ public void SetCookieValue(string cookieName, string value) =>
+ _httpContextAccessor.HttpContext?.Response.Cookies.Append(cookieName, value, new CookieOptions());
+
+ public bool HasCookie(string cookieName) => !(GetCookieValue(cookieName) is null);
}
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
index 644938082f..57f1e288b7 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
@@ -1,5 +1,3 @@
-using System;
-using System.IO;
using Microsoft.AspNetCore.DataProtection.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
@@ -12,197 +10,200 @@ using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Extensions;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
-namespace Umbraco.Cms.Web.Common.AspNetCore
+namespace Umbraco.Cms.Web.Common.AspNetCore;
+
+public class AspNetCoreHostingEnvironment : IHostingEnvironment
{
- public class AspNetCoreHostingEnvironment : IHostingEnvironment
- {
- private readonly ConcurrentHashSet _applicationUrls = new ConcurrentHashSet();
- private readonly IOptionsMonitor _hostingSettings;
- private readonly IOptionsMonitor _webRoutingSettings;
- private readonly IWebHostEnvironment _webHostEnvironment;
- private readonly IApplicationDiscriminator? _applicationDiscriminator;
+ private readonly IApplicationDiscriminator? _applicationDiscriminator;
+ private readonly ConcurrentHashSet _applicationUrls = new();
+ private readonly IOptionsMonitor _hostingSettings;
+ private readonly IWebHostEnvironment _webHostEnvironment;
+ private readonly IOptionsMonitor _webRoutingSettings;
- private string? _applicationId;
- private string? _localTempPath;
+ private readonly UrlMode _urlProviderMode;
- private UrlMode _urlProviderMode;
+ private string? _applicationId;
+ private string? _localTempPath;
- [Obsolete("Please use an alternative constructor.")]
- public AspNetCoreHostingEnvironment(
- IServiceProvider serviceProvider,
- IOptionsMonitor hostingSettings,
- IOptionsMonitor webRoutingSettings,
- IWebHostEnvironment webHostEnvironment)
+ [Obsolete("Please use an alternative constructor.")]
+ public AspNetCoreHostingEnvironment(
+ IServiceProvider serviceProvider,
+ IOptionsMonitor hostingSettings,
+ IOptionsMonitor webRoutingSettings,
+ IWebHostEnvironment webHostEnvironment)
: this(hostingSettings, webRoutingSettings, webHostEnvironment, serviceProvider.GetService()!)
+ {
+ }
+
+ public AspNetCoreHostingEnvironment(
+ IOptionsMonitor hostingSettings,
+ IOptionsMonitor webRoutingSettings,
+ IWebHostEnvironment webHostEnvironment,
+ IApplicationDiscriminator applicationDiscriminator)
+ : this(hostingSettings, webRoutingSettings, webHostEnvironment) =>
+ _applicationDiscriminator = applicationDiscriminator;
+
+ public AspNetCoreHostingEnvironment(
+ IOptionsMonitor hostingSettings,
+ IOptionsMonitor webRoutingSettings,
+ IWebHostEnvironment webHostEnvironment)
+ {
+ _hostingSettings = hostingSettings ?? throw new ArgumentNullException(nameof(hostingSettings));
+ _webRoutingSettings = webRoutingSettings ?? throw new ArgumentNullException(nameof(webRoutingSettings));
+ _webHostEnvironment = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
+ _urlProviderMode = _webRoutingSettings.CurrentValue.UrlProviderMode;
+
+ SetSiteName(hostingSettings.CurrentValue.SiteName);
+
+ // We have to ensure that the OptionsMonitor is an actual options monitor since we have a hack
+ // where we initially use an OptionsMonitorAdapter, which doesn't implement OnChange.
+ // See summery of OptionsMonitorAdapter for more information.
+ if (hostingSettings is OptionsMonitor)
{
+ hostingSettings.OnChange(settings => SetSiteName(settings.SiteName));
}
- public AspNetCoreHostingEnvironment(
- IOptionsMonitor hostingSettings,
- IOptionsMonitor webRoutingSettings,
- IWebHostEnvironment webHostEnvironment,
- IApplicationDiscriminator applicationDiscriminator)
- : this(hostingSettings, webRoutingSettings, webHostEnvironment) =>
- _applicationDiscriminator = applicationDiscriminator;
+ ApplicationPhysicalPath = webHostEnvironment.ContentRootPath;
- public AspNetCoreHostingEnvironment(
- IOptionsMonitor hostingSettings,
- IOptionsMonitor webRoutingSettings,
- IWebHostEnvironment webHostEnvironment)
+ if (_webRoutingSettings.CurrentValue.UmbracoApplicationUrl is not null)
{
- _hostingSettings = hostingSettings ?? throw new ArgumentNullException(nameof(hostingSettings));
- _webRoutingSettings = webRoutingSettings ?? throw new ArgumentNullException(nameof(webRoutingSettings));
- _webHostEnvironment = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
- _urlProviderMode = _webRoutingSettings.CurrentValue.UrlProviderMode;
-
- SetSiteName(hostingSettings.CurrentValue.SiteName);
-
- // We have to ensure that the OptionsMonitor is an actual options monitor since we have a hack
- // where we initially use an OptionsMonitorAdapter, which doesn't implement OnChange.
- // See summery of OptionsMonitorAdapter for more information.
- if (hostingSettings is OptionsMonitor)
- {
- hostingSettings.OnChange(settings => SetSiteName(settings.SiteName));
- }
-
- ApplicationPhysicalPath = webHostEnvironment.ContentRootPath;
-
- if (_webRoutingSettings.CurrentValue.UmbracoApplicationUrl is not null)
- {
- ApplicationMainUrl = new Uri(_webRoutingSettings.CurrentValue.UmbracoApplicationUrl);
- }
+ ApplicationMainUrl = new Uri(_webRoutingSettings.CurrentValue.UmbracoApplicationUrl);
}
+ }
- ///
- public bool IsHosted { get; } = true;
+ // Scheduled for removal in v12
+ [Obsolete("This will never have a value")]
+ public Version? IISVersion { get; }
- ///
- public Uri ApplicationMainUrl { get; private set; } = null!;
+ ///
+ public bool IsHosted { get; } = true;
- ///
- public string SiteName { get; private set; } = null!;
+ ///
+ public Uri ApplicationMainUrl { get; private set; } = null!;
- ///
- public string ApplicationId
+ ///
+ public string SiteName { get; private set; } = null!;
+
+ ///
+ public string ApplicationId
+ {
+ get
{
- get
+ if (_applicationId != null)
{
- if (_applicationId != null)
- {
- return _applicationId;
- }
-
- _applicationId = _applicationDiscriminator?.GetApplicationId() ?? _webHostEnvironment.GetTemporaryApplicationId();
-
return _applicationId;
}
+
+ _applicationId = _applicationDiscriminator?.GetApplicationId() ??
+ _webHostEnvironment.GetTemporaryApplicationId();
+
+ return _applicationId;
}
-
- ///
- public string ApplicationPhysicalPath { get; }
-
- // TODO how to find this, This is a server thing, not application thing.
- public string ApplicationVirtualPath => _hostingSettings.CurrentValue.ApplicationVirtualPath?.EnsureStartsWith('/') ?? "/";
-
- ///
- public bool IsDebugMode => _hostingSettings.CurrentValue.Debug;
-
- public Version? IISVersion { get; }
-
- public string LocalTempPath
- {
- get
- {
- if (_localTempPath != null)
- {
- return _localTempPath;
- }
-
- switch (_hostingSettings.CurrentValue.LocalTempStorageLocation)
- {
- case LocalTempStorage.EnvironmentTemp:
-
- // environment temp is unique, we need a folder per site
-
- // use a hash
- // combine site name and application id
- // site name is a Guid on Cloud
- // application id is eg /LM/W3SVC/123456/ROOT
- // the combination is unique on one server
- // and, if a site moves from worker A to B and then back to A...
- // hopefully it gets a new Guid or new application id?
- string hashString = SiteName + "::" + ApplicationId;
- string hash = hashString.GenerateHash();
- string siteTemp = Path.Combine(Path.GetTempPath(), "UmbracoData", hash);
-
- return _localTempPath = siteTemp;
-
- default:
-
- return _localTempPath = MapPathContentRoot(Cms.Core.Constants.SystemDirectories.TempData);
- }
- }
- }
-
- ///
- public string MapPathWebRoot(string path) => _webHostEnvironment.MapPathWebRoot(path);
-
- ///
- public string MapPathContentRoot(string path) => _webHostEnvironment.MapPathContentRoot(path);
-
- ///
- public string ToAbsolute(string virtualPath)
- {
- if (!virtualPath.StartsWith("~/") && !virtualPath.StartsWith("/") && _urlProviderMode != UrlMode.Absolute)
- {
- throw new InvalidOperationException($"The value {virtualPath} for parameter {nameof(virtualPath)} must start with ~/ or /");
- }
-
- // will occur if it starts with "/"
- if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute))
- {
- return virtualPath;
- }
-
- string fullPath = ApplicationVirtualPath.EnsureEndsWith('/') + virtualPath.TrimStart(Core.Constants.CharArrays.TildeForwardSlash);
-
- return fullPath;
- }
-
- public void EnsureApplicationMainUrl(Uri? currentApplicationUrl)
- {
- // Fixme: This causes problems with site swap on azure because azure pre-warms a site by calling into `localhost` and when it does that
- // it changes the URL to `localhost:80` which actually doesn't work for pinging itself, it only works internally in Azure. The ironic part
- // about this is that this is here specifically for the slot swap scenario https://issues.umbraco.org/issue/U4-10626
-
- // see U4-10626 - in some cases we want to reset the application url
- // (this is a simplified version of what was in 7.x)
- // note: should this be optional? is it expensive?
-
-
- if (currentApplicationUrl is null)
- {
- return;
- }
-
- if (_webRoutingSettings.CurrentValue.UmbracoApplicationUrl is not null)
- {
- return;
- }
-
- var change = !_applicationUrls.Contains(currentApplicationUrl);
- if (change)
- {
- if (_applicationUrls.TryAdd(currentApplicationUrl))
- {
- ApplicationMainUrl = currentApplicationUrl;
- }
- }
- }
-
- private void SetSiteName(string? siteName) =>
- SiteName = string.IsNullOrWhiteSpace(siteName)
- ? _webHostEnvironment.ApplicationName
- : siteName;
}
+
+ ///
+ public string ApplicationPhysicalPath { get; }
+
+ // TODO how to find this, This is a server thing, not application thing.
+ public string ApplicationVirtualPath =>
+ _hostingSettings.CurrentValue.ApplicationVirtualPath?.EnsureStartsWith('/') ?? "/";
+
+ ///
+ public bool IsDebugMode => _hostingSettings.CurrentValue.Debug;
+
+ public string LocalTempPath
+ {
+ get
+ {
+ if (_localTempPath != null)
+ {
+ return _localTempPath;
+ }
+
+ switch (_hostingSettings.CurrentValue.LocalTempStorageLocation)
+ {
+ case LocalTempStorage.EnvironmentTemp:
+
+ // environment temp is unique, we need a folder per site
+
+ // use a hash
+ // combine site name and application id
+ // site name is a Guid on Cloud
+ // application id is eg /LM/W3SVC/123456/ROOT
+ // the combination is unique on one server
+ // and, if a site moves from worker A to B and then back to A...
+ // hopefully it gets a new Guid or new application id?
+ var hashString = SiteName + "::" + ApplicationId;
+ var hash = hashString.GenerateHash();
+ var siteTemp = Path.Combine(Path.GetTempPath(), "UmbracoData", hash);
+
+ return _localTempPath = siteTemp;
+
+ default:
+
+ return _localTempPath = MapPathContentRoot(Core.Constants.SystemDirectories.TempData);
+ }
+ }
+ }
+
+ ///
+ public string MapPathWebRoot(string path) => _webHostEnvironment.MapPathWebRoot(path);
+
+ ///
+ public string MapPathContentRoot(string path) => _webHostEnvironment.MapPathContentRoot(path);
+
+ ///
+ public string ToAbsolute(string virtualPath)
+ {
+ if (!virtualPath.StartsWith("~/") && !virtualPath.StartsWith("/") && _urlProviderMode != UrlMode.Absolute)
+ {
+ throw new InvalidOperationException(
+ $"The value {virtualPath} for parameter {nameof(virtualPath)} must start with ~/ or /");
+ }
+
+ // will occur if it starts with "/"
+ if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute))
+ {
+ return virtualPath;
+ }
+
+ var fullPath = ApplicationVirtualPath.EnsureEndsWith('/') +
+ virtualPath.TrimStart(Core.Constants.CharArrays.TildeForwardSlash);
+
+ return fullPath;
+ }
+
+ public void EnsureApplicationMainUrl(Uri? currentApplicationUrl)
+ {
+ // Fixme: This causes problems with site swap on azure because azure pre-warms a site by calling into `localhost` and when it does that
+ // it changes the URL to `localhost:80` which actually doesn't work for pinging itself, it only works internally in Azure. The ironic part
+ // about this is that this is here specifically for the slot swap scenario https://issues.umbraco.org/issue/U4-10626
+
+ // see U4-10626 - in some cases we want to reset the application url
+ // (this is a simplified version of what was in 7.x)
+ // note: should this be optional? is it expensive?
+ if (currentApplicationUrl is null)
+ {
+ return;
+ }
+
+ if (_webRoutingSettings.CurrentValue.UmbracoApplicationUrl is not null)
+ {
+ return;
+ }
+
+ var change = !_applicationUrls.Contains(currentApplicationUrl);
+ if (change)
+ {
+ if (_applicationUrls.TryAdd(currentApplicationUrl))
+ {
+ ApplicationMainUrl = currentApplicationUrl;
+ }
+ }
+ }
+
+ private void SetSiteName(string? siteName) =>
+ SiteName = string.IsNullOrWhiteSpace(siteName)
+ ? _webHostEnvironment.ApplicationName
+ : siteName;
}
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreIpResolver.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreIpResolver.cs
index d7683e1ffe..d9bc76f8fa 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreIpResolver.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreIpResolver.cs
@@ -1,17 +1,14 @@
using Microsoft.AspNetCore.Http;
using Umbraco.Cms.Core.Net;
-namespace Umbraco.Cms.Web.Common.AspNetCore
+namespace Umbraco.Cms.Web.Common.AspNetCore;
+
+public class AspNetCoreIpResolver : IIpResolver
{
- public class AspNetCoreIpResolver : IIpResolver
- {
- private readonly IHttpContextAccessor _httpContextAccessor;
+ private readonly IHttpContextAccessor _httpContextAccessor;
- public AspNetCoreIpResolver(IHttpContextAccessor httpContextAccessor)
- {
- _httpContextAccessor = httpContextAccessor;
- }
+ public AspNetCoreIpResolver(IHttpContextAccessor httpContextAccessor) => _httpContextAccessor = httpContextAccessor;
- public string GetCurrentRequestIpAddress() => _httpContextAccessor?.HttpContext?.Connection?.RemoteIpAddress?.ToString() ?? string.Empty;
- }
+ public string GetCurrentRequestIpAddress() =>
+ _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString() ?? string.Empty;
}
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreMarchal.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreMarchal.cs
index bd9d4439e2..dbf9a2d4d3 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreMarchal.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreMarchal.cs
@@ -1,13 +1,10 @@
-using System;
using System.Runtime.InteropServices;
using Umbraco.Cms.Core.Diagnostics;
-namespace Umbraco.Cms.Web.Common.AspNetCore
-{
+namespace Umbraco.Cms.Web.Common.AspNetCore;
- public class AspNetCoreMarchal : IMarchal
- {
- // This thing is not available in net standard, but exists in both .Net 4 and .Net Core 3
- public IntPtr GetExceptionPointers() => Marshal.GetExceptionPointers();
- }
+public class AspNetCoreMarchal : IMarchal
+{
+ // This thing is not available in net standard, but exists in both .Net 4 and .Net Core 3
+ public IntPtr GetExceptionPointers() => Marshal.GetExceptionPointers();
}
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCorePasswordHasher.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCorePasswordHasher.cs
index 17c1306789..d9aed0be81 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCorePasswordHasher.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCorePasswordHasher.cs
@@ -1,19 +1,13 @@
using Microsoft.AspNetCore.Identity;
+using Umbraco.Cms.Core.Security;
-namespace Umbraco.Cms.Web.Common.AspNetCore
+namespace Umbraco.Cms.Web.Common.AspNetCore;
+
+public class AspNetCorePasswordHasher : IPasswordHasher
{
- public class AspNetCorePasswordHasher : Cms.Core.Security.IPasswordHasher
- {
- private PasswordHasher