diff --git a/src/Umbraco.Cms.Api.Common/Mvc/ActionResults/EmptyCreatedAtActionResult.cs b/src/Umbraco.Cms.Api.Common/Mvc/ActionResults/EmptyCreatedAtActionResult.cs
new file mode 100644
index 0000000000..0a50a87ccf
--- /dev/null
+++ b/src/Umbraco.Cms.Api.Common/Mvc/ActionResults/EmptyCreatedAtActionResult.cs
@@ -0,0 +1,46 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Routing;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Umbraco.Cms.Api.Common.Mvc.ActionResults;
+
+///
+/// A "created at" action result with no response body.
+///
+public sealed class EmptyCreatedAtActionResult : ActionResult
+{
+ private readonly string? _actionName;
+ private readonly string? _controllerName;
+ private readonly object? _routeValues;
+
+ public EmptyCreatedAtActionResult(string? actionName, string? controllerName, object? routeValues)
+ {
+ _actionName = actionName;
+ _controllerName = controllerName;
+ _routeValues = routeValues;
+ }
+
+ public override void ExecuteResult(ActionContext context)
+ {
+ ArgumentNullException.ThrowIfNull(context);
+
+ HttpRequest request = context.HttpContext.Request;
+ IUrlHelper urlHelper = context.HttpContext.RequestServices.GetRequiredService().GetUrlHelper(context);
+
+ var url = urlHelper.Action(
+ _actionName,
+ _controllerName,
+ _routeValues,
+ request.Scheme,
+ request.Host.ToUriComponent());
+
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new InvalidOperationException("No routes could be found that matched the provided route components");
+ }
+
+ context.HttpContext.Response.StatusCode = StatusCodes.Status201Created;
+ context.HttpContext.Response.Headers.Location = url;
+ }
+}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs
index ea824f40ca..40773d3bbe 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs
@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.Attributes;
using Umbraco.Cms.Api.Common.Filters;
+using Umbraco.Cms.Api.Common.Mvc.ActionResults;
using Umbraco.Cms.Api.Management.DependencyInjection;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Features;
@@ -18,10 +19,10 @@ namespace Umbraco.Cms.Api.Management.Controllers;
[JsonOptionsName(Constants.JsonOptionsNames.BackOffice)]
public abstract class ManagementApiControllerBase : Controller, IUmbracoFeature
{
- protected CreatedAtActionResult CreatedAtAction(Expression> action, Guid id)
+ protected IActionResult CreatedAtAction(Expression> action, Guid id)
=> CreatedAtAction(action, new { id = id });
- protected CreatedAtActionResult CreatedAtAction(Expression> action, object routeValues)
+ protected IActionResult CreatedAtAction(Expression> action, object routeValues)
{
if (action.Body is not ConstantExpression constantExpression)
{
@@ -31,10 +32,10 @@ public abstract class ManagementApiControllerBase : Controller, IUmbracoFeature
var controllerName = ManagementApiRegexes.ControllerTypeToNameRegex().Replace(typeof(T).Name, string.Empty);
var actionName = constantExpression.Value?.ToString() ?? throw new ArgumentException("Expression does not have a value.");
- return base.CreatedAtAction(actionName, controllerName, routeValues, null);
+ return new EmptyCreatedAtActionResult(actionName, controllerName, routeValues);
}
- protected CreatedAtActionResult CreatedAtAction(Expression> action, string name)
+ protected IActionResult CreatedAtAction(Expression> action, string name)
{
if (action.Body is not ConstantExpression constantExpression)
{
@@ -44,7 +45,7 @@ public abstract class ManagementApiControllerBase : Controller, IUmbracoFeature
var controllerName = ManagementApiRegexes.ControllerTypeToNameRegex().Replace(typeof(T).Name, string.Empty);
var actionName = constantExpression.Value?.ToString() ?? throw new ArgumentException("Expression does not have a value.");
- return base.CreatedAtAction(actionName, controllerName, new { name = name }, null);
+ return new EmptyCreatedAtActionResult(actionName, controllerName, new { name = name });
}
protected static Guid CurrentUserKey(IBackOfficeSecurityAccessor backOfficeSecurityAccessor)