diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index b2e6ac484f..c14b41f13f 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -61,7 +61,7 @@ This guide describes each step to make your first contribution:
## Further contribution guides
- [Before you start](contributing-before-you-start.md)
-- [Finding your first issue: Up for grabs](contributing-before-you-start.md)
+- [Finding your first issue: Up for grabs](contributing-first-issue.md)
- [Contributing to the new backoffice](https://docs.umbraco.com/umbraco-backoffice/)
- [Unwanted changes](contributing-unwanted-changes.md)
- [Other ways to contribute](contributing-other-ways-to-contribute.md)
diff --git a/.github/workflows/azure-backoffice.yml b/.github/workflows/azure-backoffice.yml
new file mode 100644
index 0000000000..46597a42fd
--- /dev/null
+++ b/.github/workflows/azure-backoffice.yml
@@ -0,0 +1,55 @@
+name: Backoffice Static Web Apps CI/CD
+
+on:
+ push:
+ branches:
+ - contrib
+ - v*/dev
+ paths:
+ - src/Umbraco.Web.UI.Client/package.json
+ - src/Umbraco.Web.UI.Client/package-lock.json
+ - src/Umbraco.Web.UI.Client/src/**
+ - .github/workflows/azure-backoffice.yml
+ pull_request:
+ types: [opened, synchronize, reopened, closed]
+ branches:
+ - contrib
+ - v*/dev
+
+jobs:
+ build_and_deploy_job:
+ if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed' && (contains(github.event.pull_request.labels.*.name, 'preview/backoffice')))
+ runs-on: ubuntu-latest
+ name: Build and Deploy Job
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: true
+ - name: Build And Deploy
+ id: builddeploy
+ uses: Azure/static-web-apps-deploy@v1
+ with:
+ production_branch: contrib
+ azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_VICTORIOUS_GROUND_017B08103 }}
+ repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
+ action: "upload"
+ ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
+ # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
+ app_location: "src/Umbraco.Web.UI.Client" # App source code path
+ app_build_command: "npm run build:for:static"
+ output_location: "dist" # Built app content directory - optional
+ skip_api_build: true # Set to true if you do not have an Azure Functions API in your repo
+ ###### End of Repository/Build Configurations ######
+
+ close_pull_request_job:
+ if: github.event_name == 'pull_request' && github.event.action == 'closed'
+ runs-on: ubuntu-latest
+ name: Close Pull Request Job
+ steps:
+ - name: Close Pull Request
+ id: closepullrequest
+ uses: Azure/static-web-apps-deploy@v1
+ with:
+ app_location: "src/Umbraco.Web.UI.Client"
+ azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_VICTORIOUS_GROUND_017B08103 }}
+ action: "close"
diff --git a/.github/workflows/azure-storybook.yml b/.github/workflows/azure-storybook.yml
new file mode 100644
index 0000000000..6702a443cb
--- /dev/null
+++ b/.github/workflows/azure-storybook.yml
@@ -0,0 +1,56 @@
+name: Storybook CI/CD
+
+on:
+ push:
+ branches:
+ - contrib
+ - v*/dev
+ paths:
+ - src/Umbraco.Web.UI.Client/package.json
+ - src/Umbraco.Web.UI.Client/package-lock.json
+ - src/Umbraco.Web.UI.Client/src/**
+ - .github/workflows/azure-storybook.yml
+ pull_request:
+ types: [opened, synchronize, reopened, closed]
+ branches:
+ - contrib
+ - v*/dev
+
+env:
+ NODE_OPTIONS: --max_old_space_size=16384
+
+jobs:
+ build_and_deploy_job:
+ if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed' && (contains(github.event.pull_request.labels.*.name, 'preview/storybook')))
+ runs-on: ubuntu-latest
+ name: Build and Deploy Job
+ steps:
+ - uses: actions/checkout@v4
+ - name: Build And Deploy
+ id: builddeploy
+ uses: Azure/static-web-apps-deploy@v1
+ with:
+ production_branch: contrib
+ azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ORANGE_SEA_0C7411A03 }}
+ repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
+ action: "upload"
+ ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
+ # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
+ app_location: "src/Umbraco.Web.UI.Client" # App source code path
+ app_build_command: "npm run storybook:build"
+ output_location: "/storybook-static" # Built app content directory - optional
+ skip_api_build: true # Set to true if you do not have an Azure Functions API in your repo
+ ###### End of Repository/Build Configurations ######
+
+ close_pull_request_job:
+ if: github.event_name == 'pull_request' && github.event.action == 'closed'
+ runs-on: ubuntu-latest
+ name: Close Pull Request Job
+ steps:
+ - name: Close Pull Request
+ id: closepullrequest
+ uses: Azure/static-web-apps-deploy@v1
+ with:
+ app_location: "src/Umbraco.Web.UI.Client"
+ azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ORANGE_SEA_0C7411A03 }}
+ action: "close"
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3119ae6509..6d4441fffc 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,8 @@
{
- "cSpell.words": [
- "unprovide"
- ]
+ "cSpell.words": ["unprovide"],
+ "eslint.useFlatConfig": true,
+ "eslint.workingDirectories": [
+ "./src/Umbraco.Web.UI.Client/",
+ "./src/Umbraco.Web.UI.Login/"
+ ]
}
diff --git a/Directory.Build.props b/Directory.Build.props
index 7e8128fd83..4dda16251e 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -20,6 +20,7 @@
false
+
false
- true
+ false
15.0.0
true
true
diff --git a/NOTICES.txt b/NOTICES.txt
new file mode 100644
index 0000000000..1ea114b715
--- /dev/null
+++ b/NOTICES.txt
@@ -0,0 +1,571 @@
+Third-Party Notices
+===================
+
+This file contains notices and attributions for third-party software used in the Umbraco CMS project.
+
+It is not a license and does not grant any rights to use the third-party software.
+
+Umbraco CMS is licensed under the MIT License, which can be found in the LICENSE file.
+
+---
+
+@openid/AppAuth-JS: An OpenID Connect and OAuth 2.0 client library for JavaScript
+
+URL: https://github.com/openid/AppAuth-JS
+License: Apache License, Version 2.0
+Copyright: 2017 Google Inc.
+
+---
+
+AutoFixture: Write maintainable unit tests, faster
+
+URL: https://github.com/AutoFixture/AutoFixture
+License: MIT License
+Copyright: 2013 Mark Seemann
+
+---
+
+Asp.Versioning.Mvc: A library for ASP.NET Core versioning
+
+URL: https://github.com/dotnet/aspnet-api-versioning
+License: MIT License
+Copyright: .NET Foundation and contributors
+
+---
+
+Babel: A JavaScript compiler
+
+URL: https://babeljs.io/
+License: MIT License
+Copyright: 2014-present Sebastian McKenzie and other contributors
+
+---
+
+BenchmarkDotNet: Powerful .NET library for benchmarking
+
+URL: https://github.com/dotnet/BenchmarkDotNet
+License: MIT License
+Copyright: .NET Foundation and Contributors
+
+---
+
+Bogus: A simple and sane data generator for populating objects that supports different locales.
+
+URL: https://github.com/bchavez/Bogus
+License: MIT License
+Copyright: 2015 Brian Chavez
+
+---
+
+CommandLineParser: Terse syntax C# command line parser for .NET
+
+URL: https://github.com/commandlineparser/commandline
+License: MIT License
+Copyright: 2005-2015 Giacomo Stelluti Scala & Contributors
+
+---
+
+cross-env: A CLI tool to set environment variables across platforms
+
+URL: https://github.com/kentcdodds/cross-env
+License: MIT License
+Copyright: 2017 Kent C. Dodds
+
+---
+
+Dazinator.Extensions.FileProviders: A library for file provider extensions
+
+URL: https://github.com/dazinator/Dazinator.Extensions.FileProviders
+License: MIT License
+Copyright: 2016 Darrell
+
+---
+
+DOMPurify: A DOM-only XSS sanitizer for HTML, MathML and SVG
+
+URL: https://github.com/cure53/DOMPurify
+License: Apache License, Version 2.0
+Copyright: 2025 Dr.-Ing. Mario Heiderich, Cure53
+
+---
+
+Element Internals Polyfill: A polyfill for the Element Internals API
+
+URL: https://github.com/calebdwilliams/element-internals-polyfill
+License: MIT License
+Copyright: 2021 Caleb Williams
+
+---
+
+Eslint: A tool for identifying and reporting on patterns in JavaScript
+
+URL: https://eslint.org/
+License: MIT License
+Copyright: OpenJS Foundation and other contributors
+
+---
+
+Examine: A search and indexing library for .NET
+
+URL: https://github.com/Shazwazza/Examine
+License: Microsoft Public License (Ms-PL)
+Copyright: 2023 Shannon Deminick
+
+---
+
+Glob: A library for matching file paths using glob patterns
+
+URL: https://github.com/isaacs/node-glob
+License: ISC License
+Copyright: 2009-2023 Isaac Z. Schlueter and Contributors
+
+---
+
+Globals: A library for managing global variables in JavaScript
+
+URL: https://github.com/sindresorhus/globals
+License: MIT License
+Copyright: Sindre Sorhus
+
+---
+
+Html Agility Pack: An HTML parser for .NET
+
+URL: https://html-agility-pack.net/
+License: MIT License
+Copyright: ZZZ Projects Inc.
+
+---
+
+ImageSharp: A cross-platform library for processing images in .NET
+
+URL: https://github.com/SixLabors/ImageSharp
+License: Apache License, Version 2.0 under the Six Labors Split License
+Copyright: Six Labors
+
+---
+
+jsdiff: A JavaScript text differencing implementation
+
+URL: https://github.com/kpdecker/jsdiff
+License: BSD 3-Clause License
+Copyright: 2009-2015 Kevin Decker
+
+---
+
+JsonPatch.Net: A library for JSON Patch (RFC 6902) in .NET
+
+URL: https://github.com/json-everything/json-everything
+License: MIT License
+Copyright: .NET Foundation and Contributors
+
+---
+
+K4os.Compression.LZ4: A fast LZ4 compression library for .NET
+
+URL: https://github.com/MiloszKrajewski/K4os.Compression.LZ4
+License: MIT License
+Copyright: 2017 Milosz Krajewski
+
+---
+
+Lit: A simple library for building fast, lightweight web components
+
+URL: https://lit.dev
+License: BSD 3-Clause License
+Copyright: 2020 Google LLC. All rights reserved.
+
+---
+
+Lucide: Beautiful & consistent icons for the web
+
+URL: https://lucide.dev/
+License: ISC License
+Copyright: 2013-2022 Cole Bemis
+Copyright: 2022 Lucide Contributors
+
+---
+
+Madge: A dependency graph generator for JavaScript
+
+URL: https://github.com/pahen/madge
+License: MIT License
+Copyright: 2017 Patrik Henningsson
+
+---
+
+MailKit: A library for sending email in .NET
+
+URL: https://github.com/jstedfast/MailKit
+License: MIT License
+Copyright: 2013-2024 .NET Foundation and Contributors
+
+---
+
+Markdown: A library for parsing and compiling Markdown
+
+URL: https://github.com/hey-red/Markdown
+License: MIT License
+Copyright: 2018 red
+
+---
+
+marked: A markdown parser and compiler
+
+URL: https://marked.js.org/
+License: MIT License
+Copyright: 2011-2018, Christopher Jeffrey (https://github.com/chjj/)
+Copyright: 2018+, MarkedJS (https://github.com/markedjs/)
+
+---
+
+Message Pack: The extremely fast MessagePack serializer for C#
+
+URL: https://github.com/MessagePack-CSharp/MessagePack-CSharp
+License: MIT License
+Copyright: 2017 Yoshifumi Kawai and contributors
+
+---
+
+Miniprofiler: A mini profiler for .NET
+
+URL: https://github.com/MiniProfiler/dotnet
+License: MIT License
+Copyright: .NET MiniProfiler Contributors
+
+---
+
+Monaco Editor: A browser-based code editor
+
+URL: https://microsoft.github.io/monaco-editor/
+License: MIT License
+Copyright: 2016-present Microsoft Corporation
+
+---
+
+Moq: A mocking library for .NET
+
+URL: https://github.com/moq/moq
+License: BSD 3-Clause License
+Copyright: 2007 Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors.
+
+---
+
+Mock Service Worker (MSW): A library for mocking API requests in JavaScript
+
+URL: https://mswjs.io/
+License: MIT License
+Copyright: 2018–present Artem Zakharchenko
+
+---
+
+NCrontab: A cron schedule parser for .NET
+
+URL: https://github.com/atifaziz/NCrontab
+License: Apache License, Version 2.0
+Copyright: 2001 The OpenSymphony Group
+Copyright: 2008 Atif Aziz
+
+---
+
+Nerdbank.GitVersioning: A library for versioning .NET projects
+
+URL: https://github.com/dotnet/Nerdbank.GitVersioning
+License: MIT License
+Copyright: .NET Foundation and Contributors
+
+---
+
+NJsonSchema: A JSON schema validator for .NET
+
+URL: https://github.com/RicoSuter/NJsonSchema
+License: MIT License
+Copyright: 2022 Rico Suter
+
+---
+
+NPoco: A micro ORM for .NET
+
+URL: https://github.com/schotime/NPoco
+License: Apache License, Version 2.0
+Copyright: Schotime
+
+---
+
+NUnit: A unit testing framework for .NET
+
+URL: https://github.com/nunit/nunit
+License: MIT License
+Copyright: Charlie Poole, Rob Prouse and Contributors
+
+---
+
+Open Web Components: A set of standards and libraries for building web components
+
+URL: https://open-wc.org/
+License: MIT License
+Copyright: 2018 open-wc
+
+---
+
+Openapi-ts: The OpenAPI to TypeScript codegen
+
+URL: https://github.com/hey-api/openapi-ts
+License: MIT License
+Copyright: Hey API
+
+---
+
+OpenIddict: A simple and flexible OpenID Connect server for ASP.NET Core
+
+URL: https://github.com/openiddict/openiddict-core
+License: Apache License, Version 2.0
+Copyright: Kévin Chalet
+
+---
+
+Playwright: A Node.js library to automate browser testing
+
+URL: https://playwright.dev/
+License: Apache License, Version 2.0
+Copyright: 2025 Microsoft Corporation
+
+---
+
+Playwright-msw: A library to wrap Mock Service Worker with Playwright
+
+URL: https://github.com/valendres/playwright-msw
+License: MIT License
+Copyright: 2022 Peter Weller
+
+---
+
+Prettier: An opinionated code formatter
+
+URL: https://prettier.io/
+License: MIT License
+Copyright: James Long and contributors
+
+---
+
+Remark-gfm: A GitHub Flavored Markdown plugin for Remark
+
+URL: https://github.com/remarkjs/remark-gfm
+License: MIT License
+Copyright: Titus Wormer
+
+---
+
+Rollup: A module bundler for JavaScript
+
+URL: https://rollupjs.org/
+License: MIT License
+Copyright: 2015-present Rollup contributors
+
+---
+
+Rollup Plugins: A collection of Rollup plugins
+
+URL: https://github.com/rollup/plugins
+License: MIT License
+Copyright: 2019-present Rollup Plugins contributors
+
+---
+
+Rollup-plugin-esbuild: A Rollup plugin for using esbuild
+
+URL: https://github.com/egoist/rollup-plugin-esbuild
+License: MIT License
+Copyright: 2020 EGOIST
+
+---
+
+Rollup-plugin-import-css: A Rollup plugin for importing CSS files
+
+URL: https://github.com/jleeson/rollup-plugin-import-css
+License: MIT License
+Copyright: 2020 Jacob Leeson
+
+---
+
+rxjs: Reactive Extensions for JavaScript
+
+URL: https://rxjs.dev/
+License: Apache License, Version 2.0
+Copyright: 2015-present Ben Lesh , Google, Inc., Netflix, Inc., Microsoft Corp., and contributors
+
+---
+
+Serilog: A diagnostic logging library for .NET
+
+URL: https://github.com/serilog/serilog
+License: Apache License, Version 2.0
+Copyright: Serilog Contributors
+
+---
+
+Simple Icons: A set of SVG icons for popular brands
+
+URL: https://simpleicons.org/
+License: CC0 1.0 Universal License
+Copyright: Simple Icons Contributors
+
+---
+
+Storybook: A UI component explorer for Web Components
+
+URL: https://storybook.js.org/
+License: MIT License
+Copyright: 2024 Storybook
+
+---
+
+StyleCop.Analyzers: Analyzers for StyleCop
+
+URL: https://github.com/DotNetAnalyzers/StyleCopAnalyzers
+License: MIT License
+Copyright: Tunnel Vision Laboratories, LLC
+
+---
+
+SVGO: A tool for optimizing SVG files
+
+URL: https://svgo.dev/
+License: MIT License
+Copyright: Kir Belevich
+
+---
+
+Swashbuckle.AspNetCore: A library for generating Swagger documentation for ASP.NET Core APIs
+
+URL: https://github.com/domaindrivendev/Swashbuckle.AspNetCore
+License: MIT License
+Copyright: 2016 Richard Morris
+
+---
+
+Tiny Glob: A tiny globbing library for Node.js
+
+URL: https://github.com/terkelg/tiny-glob
+License: MIT License
+Copyright: 2018 Terkel
+
+---
+
+Tiptap: A renderless rich-text editor for the web
+
+URL: https://tiptap.dev/
+License: MIT License
+Copyright: 2025 Tiptap GmbH
+
+---
+
+Tsc-alias: A TypeScript compiler plugin for aliasing module paths
+
+URL: https://github.com/justkey007/tsc-alias
+License: MIT License
+Copyright: 2018 Justkey
+
+---
+
+Typedoc: A documentation generator for TypeScript projects
+
+URL: https://typedoc.org/
+License: Apache License, Version 2.0
+Copyright: Gerrit Birkeland and Contributors
+
+---
+
+Typescript: A typed superset of JavaScript that compiles to plain JavaScript
+
+URL: https://www.typescriptlang.org/
+License: Apache License, Version 2.0
+Copyright: 2012-present Microsoft Corporation
+
+---
+
+Typescript-eslint: A set of tools for linting TypeScript code
+
+URL: https://github.com/typescript-eslint/typescript-eslint
+License: MIT License
+Copyright: 2019 typescript-eslint and other contributors
+
+---
+
+Typescript-json-schema: A library for generating JSON schema from TypeScript types
+
+URL: https://github.com/YousefED/typescript-json-schema
+License: BSD 3-Clause License
+Copyright: 2016 typescript-json-schema contributors
+
+---
+
+Umbraco.Code: Provides code-level tools for Umbraco
+
+URL: https://github.com/umbraco/Umbraco-Code
+License: MIT License
+Copyright: 2005-present Umbraco A/S
+
+---
+
+Umbraco.GitVersioning.Extensions: Utilities for Nerdbank.GitVersioning
+
+URL: https://github.com/umbraco/Umbraco.GitVersioning.Extensions
+License: MIT License
+Copyright: 2005-present Umbraco A/S
+
+---
+
+Umbraco.JsonSchema.Extensions: Utilities for JSON schema generation
+
+URL: https://github.com/umbraco/Umbraco.JsonSchema.Extensions
+License: MIT License
+Copyright: 2005-present Umbraco A/S
+
+---
+
+Umbraco UI Library: A set of UI components for building web applications
+
+URL: https://uui.umbraco.com/
+License: MIT License
+Copyright: 2005-present Umbraco A/S
+
+---
+
+uuid: A library for generating unique identifiers
+
+URL: https://github.com/uuidjs/uuid
+License: MIT License
+Copyright: 2010-2020 Robert Kieffer and other contributors
+
+---
+
+Vite: A fast build tool and development server for modern web projects
+
+URL: https://vite.dev/
+License: MIT License
+Copyright: 2019-present VoidZero Inc. and Vite contributors
+
+---
+
+Vite-plugin-static-copy: A Vite plugin for copying static files
+
+URL: https://github.com/sapphi-red/vite-plugin-static-copy
+License: MIT License
+Copyright: 2021 sapphi-red
+
+---
+
+Vite-tsconfig-paths: A Vite plugin for resolving TypeScript paths
+
+URL: https://github.com/aleclarson/vite-tsconfig-paths
+License: MIT License
+Copyright: Alec Larson
+
+---
+
+Web Component Analyzer: A tool for analyzing web components
+
+URL: https://github.com/runem/web-component-analyzer
+License: MIT License
+Copyright: 2019 Rune Mehlsen
diff --git a/Umbraco.Client.code-workspace b/Umbraco.Client.code-workspace
new file mode 100644
index 0000000000..74e21add7e
--- /dev/null
+++ b/Umbraco.Client.code-workspace
@@ -0,0 +1,10 @@
+{
+ "folders": [
+ {
+ "path": "src/Umbraco.Web.UI.Client"
+ },
+ {
+ "path": "src/Umbraco.Web.UI.Login"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/build/nightly-E2E-test-pipelines.yml b/build/nightly-E2E-test-pipelines.yml
index 8cbb065cd7..2cb8237e25 100644
--- a/build/nightly-E2E-test-pipelines.yml
+++ b/build/nightly-E2E-test-pipelines.yml
@@ -10,6 +10,7 @@ schedules:
include:
- v14/dev
- v15/dev
+ - v16/dev
variables:
nodeVersion: 20
@@ -428,7 +429,7 @@ stages:
inputs:
targetPath: $(Build.ArtifactStagingDirectory)
artifact: "Acceptance Test Results - $(Agent.JobName) - Attempt #$(System.JobAttempt)"
-
+
# Publish test results
- task: PublishTestResults@2
displayName: "Publish test results"
diff --git a/src/Umbraco.Cms.Api.Common/Configuration/ConfigureUmbracoSwaggerGenOptions.cs b/src/Umbraco.Cms.Api.Common/Configuration/ConfigureUmbracoSwaggerGenOptions.cs
index d569d0a6a5..e4b60877f1 100644
--- a/src/Umbraco.Cms.Api.Common/Configuration/ConfigureUmbracoSwaggerGenOptions.cs
+++ b/src/Umbraco.Cms.Api.Common/Configuration/ConfigureUmbracoSwaggerGenOptions.cs
@@ -7,7 +7,6 @@ using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Umbraco.Cms.Api.Common.OpenApi;
-using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Common.Configuration;
@@ -18,13 +17,6 @@ public class ConfigureUmbracoSwaggerGenOptions : IConfigureOptions())
- { }
-
public ConfigureUmbracoSwaggerGenOptions(
IOperationIdSelector operationIdSelector,
ISchemaIdSelector schemaIdSelector,
diff --git a/src/Umbraco.Cms.Api.Common/OpenApi/IOperationIdSelector.cs b/src/Umbraco.Cms.Api.Common/OpenApi/IOperationIdSelector.cs
index 3f97e78165..441279a66b 100644
--- a/src/Umbraco.Cms.Api.Common/OpenApi/IOperationIdSelector.cs
+++ b/src/Umbraco.Cms.Api.Common/OpenApi/IOperationIdSelector.cs
@@ -5,8 +5,5 @@ namespace Umbraco.Cms.Api.Common.OpenApi;
public interface IOperationIdSelector
{
- [Obsolete("Use overload that only takes ApiDescription instead. This will be removed in Umbraco 15.")]
- string? OperationId(ApiDescription apiDescription, ApiVersioningOptions apiVersioningOptions);
-
string? OperationId(ApiDescription apiDescription);
}
diff --git a/src/Umbraco.Cms.Api.Common/OpenApi/OperationIdSelector.cs b/src/Umbraco.Cms.Api.Common/OpenApi/OperationIdSelector.cs
index 3c00a126be..8a599b2721 100644
--- a/src/Umbraco.Cms.Api.Common/OpenApi/OperationIdSelector.cs
+++ b/src/Umbraco.Cms.Api.Common/OpenApi/OperationIdSelector.cs
@@ -16,9 +16,6 @@ public class OperationIdSelector : IOperationIdSelector
public OperationIdSelector(IEnumerable operationIdHandlers)
=> _operationIdHandlers = operationIdHandlers;
- [Obsolete("Use overload that only takes ApiDescription instead. This will be removed in Umbraco 15.")]
- public virtual string? OperationId(ApiDescription apiDescription, ApiVersioningOptions apiVersioningOptions) => OperationId(apiDescription);
-
public virtual string? OperationId(ApiDescription apiDescription)
{
IOperationIdHandler? handler = _operationIdHandlers.FirstOrDefault(h => h.CanHandle(apiDescription));
diff --git a/src/Umbraco.Cms.Api.Common/OpenApi/SubTypesSelector.cs b/src/Umbraco.Cms.Api.Common/OpenApi/SubTypesSelector.cs
index c6e172f3f7..947e7a8197 100644
--- a/src/Umbraco.Cms.Api.Common/OpenApi/SubTypesSelector.cs
+++ b/src/Umbraco.Cms.Api.Common/OpenApi/SubTypesSelector.cs
@@ -10,12 +10,12 @@ namespace Umbraco.Cms.Api.Common.OpenApi;
public class SubTypesSelector : ISubTypesSelector
{
- private readonly IOptions _settings;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IEnumerable _subTypeHandlers;
private readonly IUmbracoJsonTypeInfoResolver _umbracoJsonTypeInfoResolver;
+ [Obsolete("The settings parameter is not required anymore, use the other constructor instead. Scheduled for removal in Umbraco 17.")]
public SubTypesSelector(
IOptions settings,
IHostingEnvironment hostingEnvironment,
@@ -23,7 +23,18 @@ public class SubTypesSelector : ISubTypesSelector
IEnumerable subTypeHandlers,
IUmbracoJsonTypeInfoResolver umbracoJsonTypeInfoResolver)
{
- _settings = settings;
+ _hostingEnvironment = hostingEnvironment;
+ _httpContextAccessor = httpContextAccessor;
+ _subTypeHandlers = subTypeHandlers;
+ _umbracoJsonTypeInfoResolver = umbracoJsonTypeInfoResolver;
+ }
+
+ public SubTypesSelector(
+ IHostingEnvironment hostingEnvironment,
+ IHttpContextAccessor httpContextAccessor,
+ IEnumerable subTypeHandlers,
+ IUmbracoJsonTypeInfoResolver umbracoJsonTypeInfoResolver)
+ {
_hostingEnvironment = hostingEnvironment;
_httpContextAccessor = httpContextAccessor;
_subTypeHandlers = subTypeHandlers;
@@ -32,7 +43,7 @@ public class SubTypesSelector : ISubTypesSelector
public IEnumerable SubTypes(Type type)
{
- var backOfficePath = _settings.Value.GetBackOfficePath(_hostingEnvironment);
+ var backOfficePath = _hostingEnvironment.GetBackOfficePath();
var swaggerPath = $"{backOfficePath}/swagger";
if (_httpContextAccessor.HttpContext?.Request.Path.StartsWithSegments(swaggerPath) ?? false)
diff --git a/src/Umbraco.Cms.Api.Common/OpenApi/SwaggerRouteTemplatePipelineFilter.cs b/src/Umbraco.Cms.Api.Common/OpenApi/SwaggerRouteTemplatePipelineFilter.cs
index 9f05f57d5a..dba0e6f56d 100644
--- a/src/Umbraco.Cms.Api.Common/OpenApi/SwaggerRouteTemplatePipelineFilter.cs
+++ b/src/Umbraco.Cms.Api.Common/OpenApi/SwaggerRouteTemplatePipelineFilter.cs
@@ -7,7 +7,7 @@ using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using Umbraco.Cms.Core;
-using Umbraco.Cms.Core.Configuration.Models;
+using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Web.Common.ApplicationBuilder;
using Umbraco.Extensions;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
@@ -30,24 +30,21 @@ public class SwaggerRouteTemplatePipelineFilter : UmbracoPipelineFilter
IOptions swaggerGenOptions = applicationBuilder.ApplicationServices.GetRequiredService>();
applicationBuilder.UseSwagger(swaggerOptions =>
- {
- swaggerOptions.RouteTemplate = SwaggerRouteTemplate(applicationBuilder);
- });
+ {
+ swaggerOptions.RouteTemplate = SwaggerRouteTemplate(applicationBuilder);
+ });
applicationBuilder.UseSwaggerUI(swaggerUiOptions => SwaggerUiConfiguration(swaggerUiOptions, swaggerGenOptions.Value, applicationBuilder));
}
protected virtual bool SwaggerIsEnabled(IApplicationBuilder applicationBuilder)
- {
- IWebHostEnvironment webHostEnvironment = applicationBuilder.ApplicationServices.GetRequiredService();
- return webHostEnvironment.IsProduction() is false;
- }
+ => applicationBuilder.ApplicationServices.GetRequiredService().IsProduction() is false;
protected virtual string SwaggerRouteTemplate(IApplicationBuilder applicationBuilder)
- => $"{GetUmbracoPath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger/{{documentName}}/swagger.json";
+ => $"{GetBackOfficePath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger/{{documentName}}/swagger.json";
protected virtual string SwaggerUiRoutePrefix(IApplicationBuilder applicationBuilder)
- => $"{GetUmbracoPath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger";
+ => $"{GetBackOfficePath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger";
protected virtual void SwaggerUiConfiguration(
SwaggerUIOptions swaggerUiOptions,
@@ -56,8 +53,7 @@ public class SwaggerRouteTemplatePipelineFilter : UmbracoPipelineFilter
{
swaggerUiOptions.RoutePrefix = SwaggerUiRoutePrefix(applicationBuilder);
- foreach ((var name, OpenApiInfo? apiInfo) in swaggerGenOptions.SwaggerGeneratorOptions.SwaggerDocs
- .OrderBy(x => x.Value.Title))
+ foreach ((var name, OpenApiInfo? apiInfo) in swaggerGenOptions.SwaggerGeneratorOptions.SwaggerDocs.OrderBy(x => x.Value.Title))
{
swaggerUiOptions.SwaggerEndpoint($"{name}/swagger.json", $"{apiInfo.Title}");
}
@@ -70,11 +66,6 @@ public class SwaggerRouteTemplatePipelineFilter : UmbracoPipelineFilter
swaggerUiOptions.OAuthUsePkce();
}
- private string GetUmbracoPath(IApplicationBuilder applicationBuilder)
- {
- GlobalSettings settings = applicationBuilder.ApplicationServices.GetRequiredService>().Value;
- IHostingEnvironment hostingEnvironment = applicationBuilder.ApplicationServices.GetRequiredService();
-
- return settings.GetBackOfficePath(hostingEnvironment);
- }
+ private string GetBackOfficePath(IApplicationBuilder applicationBuilder)
+ => applicationBuilder.ApplicationServices.GetRequiredService().GetBackOfficePath();
}
diff --git a/src/Umbraco.Cms.Api.Delivery/Configuration/ConfigureUmbracoMemberAuthenticationDeliveryApiSwaggerGenOptions.cs b/src/Umbraco.Cms.Api.Delivery/Configuration/ConfigureUmbracoMemberAuthenticationDeliveryApiSwaggerGenOptions.cs
index 1c821f9681..5eaa75002c 100644
--- a/src/Umbraco.Cms.Api.Delivery/Configuration/ConfigureUmbracoMemberAuthenticationDeliveryApiSwaggerGenOptions.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Configuration/ConfigureUmbracoMemberAuthenticationDeliveryApiSwaggerGenOptions.cs
@@ -48,7 +48,7 @@ public class ConfigureUmbracoMemberAuthenticationDeliveryApiSwaggerGenOptions :
Id = AuthSchemeName,
}
},
- new string[] { }
+ []
}
}
};
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdContentApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdContentApiController.cs
index 523c496956..775b81803d 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdContentApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdContentApiController.cs
@@ -1,4 +1,3 @@
-using System.Diagnostics;
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -8,7 +7,6 @@ using Umbraco.Cms.Core.Models.PublishedContent;
namespace Umbraco.Cms.Api.Delivery.Controllers.Content;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ByIdContentApiController : ContentApiItemControllerBase
{
@@ -21,16 +19,6 @@ public class ByIdContentApiController : ContentApiItemControllerBase
: base(apiPublishedContentCache, apiContentResponseBuilder)
=> _requestMemberAccessService = requestMemberAccessService;
- [HttpGet("item/{id:guid}")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(IApiContentResponse), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status401Unauthorized)]
- [ProducesResponseType(StatusCodes.Status403Forbidden)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task ById(Guid id)
- => await HandleRequest(id);
-
///
/// Gets a content item by id.
///
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdsContentApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdsContentApiController.cs
index 0771c35758..150a1828ef 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdsContentApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByIdsContentApiController.cs
@@ -8,7 +8,6 @@ using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Delivery.Controllers.Content;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ByIdsContentApiController : ContentApiItemControllerBase
{
@@ -21,15 +20,6 @@ public class ByIdsContentApiController : ContentApiItemControllerBase
: base(apiPublishedContentCache, apiContentResponseBuilder)
=> _requestMemberAccessService = requestMemberAccessService;
- [HttpGet("item")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status401Unauthorized)]
- [ProducesResponseType(StatusCodes.Status403Forbidden)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task Item([FromQuery(Name = "id")] HashSet ids)
- => await HandleRequest(ids);
-
///
/// Gets content items by ids.
///
@@ -58,6 +48,6 @@ public class ByIdsContentApiController : ContentApiItemControllerBase
.WhereNotNull()
.ToArray();
- return await Task.FromResult(Ok(apiContentItems));
+ return Ok(apiContentItems);
}
}
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByRouteContentApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByRouteContentApiController.cs
index 54fe5785a9..7bc549fe33 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByRouteContentApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByRouteContentApiController.cs
@@ -1,17 +1,13 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DeliveryApi;
-using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.DeliveryApi;
using Umbraco.Cms.Core.Models.PublishedContent;
-using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Delivery.Controllers.Content;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ByRouteContentApiController : ContentApiItemControllerBase
{
@@ -21,45 +17,6 @@ public class ByRouteContentApiController : ContentApiItemControllerBase
private readonly IRequestMemberAccessService _requestMemberAccessService;
private const string PreviewContentRequestPathPrefix = $"/{Constants.DeliveryApi.Routing.PreviewContentPathPrefix}";
- [Obsolete($"Please use the constructor that accepts {nameof(IApiContentPathResolver)}. Will be removed in V15.")]
- public ByRouteContentApiController(
- IApiPublishedContentCache apiPublishedContentCache,
- IApiContentResponseBuilder apiContentResponseBuilder,
- IRequestRoutingService requestRoutingService,
- IRequestRedirectService requestRedirectService,
- IRequestPreviewService requestPreviewService,
- IRequestMemberAccessService requestMemberAccessService)
- : this(
- apiPublishedContentCache,
- apiContentResponseBuilder,
- requestRedirectService,
- requestPreviewService,
- requestMemberAccessService,
- StaticServiceProvider.Instance.GetRequiredService())
- {
- }
-
- [Obsolete($"Please use the non-obsolete constructor. Will be removed in V15.")]
- public ByRouteContentApiController(
- IApiPublishedContentCache apiPublishedContentCache,
- IApiContentResponseBuilder apiContentResponseBuilder,
- IPublicAccessService publicAccessService,
- IRequestRoutingService requestRoutingService,
- IRequestRedirectService requestRedirectService,
- IRequestPreviewService requestPreviewService,
- IRequestMemberAccessService requestMemberAccessService,
- IApiContentPathResolver apiContentPathResolver)
- : this(
- apiPublishedContentCache,
- apiContentResponseBuilder,
- requestRedirectService,
- requestPreviewService,
- requestMemberAccessService,
- apiContentPathResolver)
- {
- }
-
- [ActivatorUtilitiesConstructor]
public ByRouteContentApiController(
IApiPublishedContentCache apiPublishedContentCache,
IApiContentResponseBuilder apiContentResponseBuilder,
@@ -75,16 +32,6 @@ public class ByRouteContentApiController : ContentApiItemControllerBase
_apiContentPathResolver = apiContentPathResolver;
}
- [HttpGet("item/{*path}")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(IApiContentResponse), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status401Unauthorized)]
- [ProducesResponseType(StatusCodes.Status403Forbidden)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task ByRoute(string path = "")
- => await HandleRequest(path);
-
///
/// Gets a content item by route.
///
@@ -117,7 +64,7 @@ public class ByRouteContentApiController : ContentApiItemControllerBase
return deniedAccessResult;
}
- return await Task.FromResult(Ok(ApiContentResponseBuilder.Build(contentItem)));
+ return Ok(ApiContentResponseBuilder.Build(contentItem));
}
IApiContentRoute? redirectRoute = _requestRedirectService.GetRedirectRoute(path);
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/QueryContentApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/QueryContentApiController.cs
index bfa45f23ec..c46329d914 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/QueryContentApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/QueryContentApiController.cs
@@ -12,7 +12,6 @@ using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Delivery.Controllers.Content;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class QueryContentApiController : ContentApiControllerBase
{
@@ -30,20 +29,6 @@ public class QueryContentApiController : ContentApiControllerBase
_requestMemberAccessService = requestMemberAccessService;
}
- [HttpGet]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
- [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task Query(
- string? fetch,
- [FromQuery] string[] filter,
- [FromQuery] string[] sort,
- int skip = 0,
- int take = 10)
- => await HandleRequest(fetch, filter, sort, skip, take);
-
///
/// Gets a paginated list of content item(s) from query.
///
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdMediaApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdMediaApiController.cs
index f7fa2f6d92..0c82a652ef 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdMediaApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdMediaApiController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models.DeliveryApi;
@@ -8,7 +8,6 @@ using Umbraco.Cms.Infrastructure.DeliveryApi;
namespace Umbraco.Cms.Api.Delivery.Controllers.Media;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ByIdMediaApiController : MediaApiControllerBase
{
@@ -19,14 +18,6 @@ public class ByIdMediaApiController : MediaApiControllerBase
{
}
- [HttpGet("item/{id:guid}")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(IApiMediaWithCropsResponse), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task ById(Guid id)
- => await HandleRequest(id);
-
///
/// Gets a media item by id.
///
@@ -36,16 +27,16 @@ public class ByIdMediaApiController : MediaApiControllerBase
[MapToApiVersion("2.0")]
[ProducesResponseType(typeof(IApiMediaWithCropsResponse), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task ByIdV20(Guid id)
- => await HandleRequest(id);
+ public Task ByIdV20(Guid id)
+ => Task.FromResult(HandleRequest(id));
- private async Task HandleRequest(Guid id)
+ private IActionResult HandleRequest(Guid id)
{
IPublishedContent? media = PublishedMediaCache.GetById(id);
if (media is null)
{
- return await Task.FromResult(NotFound());
+ return NotFound();
}
return Ok(BuildApiMediaWithCrops(media));
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdsMediaApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdsMediaApiController.cs
index 957c982c38..45fad21cf9 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdsMediaApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByIdsMediaApiController.cs
@@ -9,7 +9,6 @@ using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Delivery.Controllers.Media;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ByIdsMediaApiController : MediaApiControllerBase
{
@@ -18,13 +17,6 @@ public class ByIdsMediaApiController : MediaApiControllerBase
{
}
- [HttpGet("item")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task Item([FromQuery(Name = "id")] HashSet ids)
- => await HandleRequest(ids);
-
///
/// Gets media items by ids.
///
@@ -33,10 +25,10 @@ public class ByIdsMediaApiController : MediaApiControllerBase
[HttpGet("items")]
[MapToApiVersion("2.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task ItemsV20([FromQuery(Name = "id")] HashSet ids)
- => await HandleRequest(ids);
+ public Task ItemsV20([FromQuery(Name = "id")] HashSet ids)
+ => Task.FromResult(HandleRequest(ids));
- private async Task HandleRequest(HashSet ids)
+ private IActionResult HandleRequest(HashSet ids)
{
IPublishedContent[] mediaItems = ids
.Select(PublishedMediaCache.GetById)
@@ -47,6 +39,6 @@ public class ByIdsMediaApiController : MediaApiControllerBase
.Select(BuildApiMediaWithCrops)
.ToArray();
- return await Task.FromResult(Ok(apiMediaItems));
+ return Ok(apiMediaItems);
}
}
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByPathMediaApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByPathMediaApiController.cs
index 0afedddffb..c2b91d0fd1 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByPathMediaApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/ByPathMediaApiController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.DeliveryApi;
@@ -9,7 +9,6 @@ using Umbraco.Cms.Infrastructure.DeliveryApi;
namespace Umbraco.Cms.Api.Delivery.Controllers.Media;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ByPathMediaApiController : MediaApiControllerBase
{
@@ -22,14 +21,6 @@ public class ByPathMediaApiController : MediaApiControllerBase
: base(publishedMediaCache, apiMediaWithCropsResponseBuilder)
=> _apiMediaQueryService = apiMediaQueryService;
- [HttpGet("item/{*path}")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(IApiMediaWithCropsResponse), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task ByPath(string path)
- => await HandleRequest(path);
-
///
/// Gets a media item by its path.
///
@@ -39,17 +30,17 @@ public class ByPathMediaApiController : MediaApiControllerBase
[MapToApiVersion("2.0")]
[ProducesResponseType(typeof(IApiMediaWithCropsResponse), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task ByPathV20(string path)
- => await HandleRequest(path);
+ public Task ByPathV20(string path)
+ => Task.FromResult(HandleRequest(path));
- private async Task HandleRequest(string path)
+ private IActionResult HandleRequest(string path)
{
path = DecodePath(path);
IPublishedContent? media = _apiMediaQueryService.GetByPath(path);
if (media is null)
{
- return await Task.FromResult(NotFound());
+ return NotFound();
}
return Ok(BuildApiMediaWithCrops(media));
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/QueryMediaApiController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/QueryMediaApiController.cs
index c61aaf8764..7c7238c850 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Media/QueryMediaApiController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Media/QueryMediaApiController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
@@ -14,7 +14,6 @@ using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Delivery.Controllers.Media;
-[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class QueryMediaApiController : MediaApiControllerBase
{
@@ -27,19 +26,6 @@ public class QueryMediaApiController : MediaApiControllerBase
: base(publishedMediaCache, apiMediaWithCropsResponseBuilder)
=> _apiMediaQueryService = apiMediaQueryService;
- [HttpGet]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
- [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
- [Obsolete("Please use version 2 of this API. Will be removed in V15.")]
- public async Task Query(
- string? fetch,
- [FromQuery] string[] filter,
- [FromQuery] string[] sort,
- int skip = 0,
- int take = 10)
- => await HandleRequest(fetch, filter, sort, skip, take);
-
///
/// Gets a paginated list of media item(s) from query.
///
@@ -53,15 +39,15 @@ public class QueryMediaApiController : MediaApiControllerBase
[MapToApiVersion("2.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
- public async Task QueryV20(
+ public Task QueryV20(
string? fetch,
[FromQuery] string[] filter,
[FromQuery] string[] sort,
int skip = 0,
int take = 10)
- => await HandleRequest(fetch, filter, sort, skip, take);
+ => Task.FromResult(HandleRequest(fetch, filter, sort, skip, take));
- private async Task HandleRequest(string? fetch, string[] filter, string[] sort, int skip, int take)
+ private IActionResult HandleRequest(string? fetch, string[] filter, string[] sort, int skip, int take)
{
Attempt, ApiMediaQueryOperationStatus> queryAttempt = _apiMediaQueryService.ExecuteQuery(fetch, filter, sort, skip, take);
@@ -79,6 +65,6 @@ public class QueryMediaApiController : MediaApiControllerBase
Items = mediaItems.Select(BuildApiMediaWithCrops)
};
- return await Task.FromResult(Ok(model));
+ return Ok(model);
}
}
diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs
index a5b085073b..139b9b2263 100644
--- a/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs
@@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
@@ -13,7 +12,6 @@ using OpenIddict.Server.AspNetCore;
using Umbraco.Cms.Api.Delivery.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
-using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Web.Common.Security;
using Umbraco.Extensions;
@@ -33,31 +31,6 @@ public class MemberController : DeliveryApiControllerBase
private readonly DeliveryApiSettings _deliveryApiSettings;
private readonly ILogger _logger;
-
- [Obsolete("Please use the non-obsolete constructor. Will be removed in V16.")]
- public MemberController(
- IHttpContextAccessor httpContextAccessor,
- IMemberSignInManager memberSignInManager,
- IMemberManager memberManager,
- IOptions deliveryApiSettings,
- ILogger logger)
- : this(memberSignInManager, memberManager, StaticServiceProvider.Instance.GetRequiredService(), deliveryApiSettings, logger)
- {
- }
-
- [Obsolete("Please use the non-obsolete constructor. Will be removed in V16.")]
- public MemberController(
- IHttpContextAccessor httpContextAccessor,
- IMemberSignInManager memberSignInManager,
- IMemberManager memberManager,
- IMemberClientCredentialsManager memberClientCredentialsManager,
- IOptions deliveryApiSettings,
- ILogger logger)
- : this(memberSignInManager, memberManager, memberClientCredentialsManager, deliveryApiSettings, logger)
- {
- }
-
- [ActivatorUtilitiesConstructor]
public MemberController(
IMemberSignInManager memberSignInManager,
IMemberManager memberManager,
diff --git a/src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs
index 89065a5d2e..cca2c8e09b 100644
--- a/src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs
+++ b/src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs
@@ -62,7 +62,6 @@ public static class UmbracoBuilderExtensions
builder.Services.AddTransient();
builder.Services.AddTransient();
builder.Services.AddTransient();
- builder.Services.AddScoped();
builder.Services.ConfigureOptions();
builder.AddUmbracoApiOpenApiUI();
diff --git a/src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs b/src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs
index 43653239b3..fdd98e1702 100644
--- a/src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs
@@ -91,7 +91,7 @@ internal sealed class InitializeMemberApplicationNotificationHandler : INotifica
}
}
- private bool ValidateRedirectUrls(Uri[] redirectUrls)
+ private bool ValidateRedirectUrls(IEnumerable redirectUrls)
{
if (redirectUrls.Any() is false)
{
diff --git a/src/Umbraco.Cms.Api.Delivery/Services/ApiMediaQueryService.cs b/src/Umbraco.Cms.Api.Delivery/Services/ApiMediaQueryService.cs
index 0eeeb4d6da..15ecaa1423 100644
--- a/src/Umbraco.Cms.Api.Delivery/Services/ApiMediaQueryService.cs
+++ b/src/Umbraco.Cms.Api.Delivery/Services/ApiMediaQueryService.cs
@@ -185,7 +185,7 @@ internal sealed class ApiMediaQueryService : IApiMediaQueryService
}
- private Attempt, ApiMediaQueryOperationStatus> PagedResult(IEnumerable children, int skip, int take)
+ private static Attempt, ApiMediaQueryOperationStatus> PagedResult(IEnumerable children, int skip, int take)
{
IPublishedContent[] childrenAsArray = children as IPublishedContent[] ?? children.ToArray();
var result = new PagedModel
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/BackOfficeLoginController.cs b/src/Umbraco.Cms.Api.Management/Controllers/BackOfficeLoginController.cs
index c6ff576b93..0416e5c303 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/BackOfficeLoginController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/BackOfficeLoginController.cs
@@ -24,7 +24,7 @@ public class BackOfficeLoginModel
public bool UserIsAlreadyLoggedIn { get; set; }
}
-[ApiExplorerSettings(IgnoreApi=true)]
+[ApiExplorerSettings(IgnoreApi = true)]
[Route(LoginPath)]
public class BackOfficeLoginController : Controller
{
@@ -51,7 +51,7 @@ public class BackOfficeLoginController : Controller
if (string.IsNullOrEmpty(model.UmbracoUrl))
{
- model.UmbracoUrl = _hostingEnvironment.ToAbsolute(Constants.System.DefaultUmbracoPath);
+ model.UmbracoUrl = _hostingEnvironment.GetBackOfficePath();
}
if (string.IsNullOrEmpty(model.ReturnUrl))
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Culture/AllCultureController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Culture/AllCultureController.cs
index 20d6770444..eb5177996a 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Culture/AllCultureController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Culture/AllCultureController.cs
@@ -1,4 +1,4 @@
-using System.Globalization;
+using System.Globalization;
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -28,7 +28,7 @@ public class AllCultureController : CultureControllerBase
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
- public async Task> GetAll(CancellationToken cancellationToken, int skip = 0, int take = 100)
+ public Task> GetAll(CancellationToken cancellationToken, int skip = 0, int take = 100)
{
CultureInfo[] all = _cultureService.GetValidCultureInfos();
@@ -38,6 +38,6 @@ public class AllCultureController : CultureControllerBase
Total = all.Length
};
- return await Task.FromResult(viewModel);
+ return Task.FromResult(viewModel);
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/References/ReferencedByDataTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/References/ReferencedByDataTypeController.cs
new file mode 100644
index 0000000000..b36815d408
--- /dev/null
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/References/ReferencedByDataTypeController.cs
@@ -0,0 +1,46 @@
+using Asp.Versioning;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Umbraco.Cms.Api.Common.ViewModels.Pagination;
+using Umbraco.Cms.Api.Management.Factories;
+using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Api.Management.Controllers.DataType.References;
+
+[ApiVersion("1.0")]
+public class ReferencedByDataTypeController : DataTypeControllerBase
+{
+ private readonly IDataTypeService _dataTypeService;
+ private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
+
+ public ReferencedByDataTypeController(IDataTypeService dataTypeService, IRelationTypePresentationFactory relationTypePresentationFactory)
+ {
+ _dataTypeService = dataTypeService;
+ _relationTypePresentationFactory = relationTypePresentationFactory;
+ }
+
+ ///
+ /// Gets a paged list of references for the current data type, so you can see where it is being used.
+ ///
+ [HttpGet("{id:guid}/referenced-by")]
+ [MapToApiVersion("1.0")]
+ [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
+ public async Task>> ReferencedBy(
+ CancellationToken cancellationToken,
+ Guid id,
+ int skip = 0,
+ int take = 20)
+ {
+ PagedModel relationItems = await _dataTypeService.GetPagedRelationsAsync(id, skip, take);
+
+ var pagedViewModel = new PagedViewModel
+ {
+ Total = relationItems.Total,
+ Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
+ };
+
+ return pagedViewModel;
+ }
+}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/ReferencesDataTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/ReferencesDataTypeController.cs
index c25586e93c..0eee28e49b 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/ReferencesDataTypeController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/ReferencesDataTypeController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -10,6 +10,7 @@ using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
+[Obsolete("Please use ReferencedByDataTypeController and the referenced-by endpoint. Scheduled for removal in Umbraco 17.")]
public class ReferencesDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/AllDictionaryController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/AllDictionaryController.cs
index b40db7607a..a0e7747243 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/AllDictionaryController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/AllDictionaryController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
@@ -38,6 +38,6 @@ public class AllDictionaryController : DictionaryControllerBase
Total = items.Length,
Items = _umbracoMapper.MapEnumerable(items.Skip(skip).Take(take))
};
- return await Task.FromResult(model);
+ return model;
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs
index 5e55924079..2b02ff541a 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs
@@ -28,7 +28,7 @@ public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase> MapTreeItemViewModels(IEnumerable dictionaryItems)
- => await Task.WhenAll(dictionaryItems.Select(CreateEntityTreeItemViewModelAsync));
+ => await MapTreeItemViewModelsAsync(dictionaryItems).ToArrayAsync();
protected override async Task>> GetAncestors(Guid descendantKey, bool includeSelf = true)
{
@@ -54,10 +54,19 @@ public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase MapTreeItemViewModelsAsync(IEnumerable dictionaryItems)
+ {
+ foreach (IDictionaryItem dictionaryItem in dictionaryItems)
+ {
+ yield return await CreateEntityTreeItemViewModelAsync(dictionaryItem);
+ }
+ }
+
private async Task CreateEntityTreeItemViewModelAsync(IDictionaryItem dictionaryItem)
{
var hasChildren = await DictionaryItemService.CountChildrenAsync(dictionaryItem.Key) > 0;
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs
index 6f2dd43824..f55c666cfc 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs
@@ -1,12 +1,10 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document.Collection;
using Umbraco.Cms.Core;
-using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
@@ -22,20 +20,6 @@ public class ByKeyDocumentCollectionController : DocumentCollectionControllerBas
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IDocumentCollectionPresentationFactory _documentCollectionPresentationFactory;
- [Obsolete("Please use the constructor taking all parameters.")]
- public ByKeyDocumentCollectionController(
- IContentListViewService contentListViewService,
- IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
- IUmbracoMapper mapper)
- : this(
- contentListViewService,
- backOfficeSecurityAccessor,
- mapper,
- StaticServiceProvider.Instance.GetRequiredService())
- {
- }
-
- [ActivatorUtilitiesConstructor]
public ByKeyDocumentCollectionController(
IContentListViewService contentListViewService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs
index 52b2f34d7f..10f1931313 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs
@@ -1,4 +1,4 @@
-using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Controllers.Content;
@@ -140,6 +140,10 @@ public abstract class DocumentControllerBase : ContentControllerBase
.WithDetail(
"An unspecified error occurred while (un)publishing. Please check the logs for additional information.")
.Build()),
+ ContentPublishingOperationStatus.TaskResultNotFound => NotFound(problemDetailsBuilder
+ .WithTitle("The result of the submitted task could not be found")
+ .Build()),
+
_ => StatusCode(StatusCodes.Status500InternalServerError, "Unknown content operation status."),
});
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs
index bea90daf42..ebefb5bfb2 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -24,13 +24,13 @@ public class ItemDocumentItemController : DocumentItemControllerBase
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task Item(
+ public Task Item(
CancellationToken cancellationToken,
[FromQuery(Name = "id")] HashSet ids)
{
if (ids.Count is 0)
{
- return Ok(Enumerable.Empty());
+ return Task.FromResult(Ok(Enumerable.Empty()));
}
IEnumerable documents = _entityService
@@ -38,6 +38,6 @@ public class ItemDocumentItemController : DocumentItemControllerBase
.OfType();
IEnumerable documentItemResponseModels = documents.Select(_documentPresentationFactory.CreateItemResponseModel);
- return await Task.FromResult(Ok(documentItemResponseModels));
+ return Task.FromResult(Ok(documentItemResponseModels));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs
index 1e8bb5054b..62e15d7e74 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs
@@ -1,4 +1,3 @@
-using System.Text.Json.Serialization;
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -22,28 +21,6 @@ public class SearchDocumentItemController : DocumentItemControllerBase
_documentPresentationFactory = documentPresentationFactory;
}
- [NonAction]
- [Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
- public async Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
- => await SearchFromParent(cancellationToken, query, skip, take);
-
- [NonAction]
- [Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
- public async Task SearchFromParent(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null)
- => await SearchWithTrashed(cancellationToken, query, null, skip, take, parentId);
-
- [NonAction]
- [Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
- [ProducesResponseType(typeof(PagedModel), StatusCodes.Status200OK)]
- public async Task SearchFromParentWithAllowedTypes(
- CancellationToken cancellationToken,
- string query,
- int skip = 0,
- int take = 100,
- Guid? parentId = null,
- [FromQuery] IEnumerable? allowedDocumentTypes = null) =>
- await SearchWithTrashed(cancellationToken, query, null, skip, take, parentId, allowedDocumentTypes);
-
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel), StatusCodes.Status200OK)]
@@ -56,13 +33,13 @@ public class SearchDocumentItemController : DocumentItemControllerBase
Guid? parentId = null,
[FromQuery] IEnumerable? allowedDocumentTypes = null)
{
- PagedModel searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Document, query, parentId, allowedDocumentTypes, trashed, skip, take);
+ PagedModel searchResult = await _indexedEntitySearchService.SearchAsync(UmbracoObjectTypes.Document, query, parentId, allowedDocumentTypes, trashed, skip, take);
var result = new PagedModel
{
Items = searchResult.Items.OfType().Select(_documentPresentationFactory.CreateItemResponseModel),
Total = searchResult.Total,
};
- return await Task.FromResult(Ok(result));
+ return Ok(result);
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/PublishDocumentWithDescendantsController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/PublishDocumentWithDescendantsController.cs
index 869bc4c880..f9d9681f07 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/PublishDocumentWithDescendantsController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/PublishDocumentWithDescendantsController.cs
@@ -35,7 +35,7 @@ public class PublishDocumentWithDescendantsController : DocumentControllerBase
[HttpPut("{id:guid}/publish-with-descendants")]
[MapToApiVersion("1.0")]
- [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(PublishWithDescendantsResultModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task PublishWithDescendants(CancellationToken cancellationToken, Guid id, PublishDocumentWithDescendantsRequestModel requestModel)
@@ -54,10 +54,15 @@ public class PublishDocumentWithDescendantsController : DocumentControllerBase
id,
requestModel.Cultures,
BuildPublishBranchFilter(requestModel),
- CurrentUserKey(_backOfficeSecurityAccessor));
+ CurrentUserKey(_backOfficeSecurityAccessor),
+ true);
- return attempt.Success
- ? Ok()
+ return attempt.Success && attempt.Result.AcceptedTaskId.HasValue
+ ? Ok(new PublishWithDescendantsResultModel
+ {
+ TaskId = attempt.Result.AcceptedTaskId.Value,
+ IsComplete = false
+ })
: DocumentPublishingOperationStatusResult(attempt.Status, failedBranchItems: attempt.Result.FailedItems);
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/PublishDocumentWithDescendantsResultController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/PublishDocumentWithDescendantsResultController.cs
new file mode 100644
index 0000000000..9a499ede1e
--- /dev/null
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/PublishDocumentWithDescendantsResultController.cs
@@ -0,0 +1,69 @@
+using Asp.Versioning;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Umbraco.Cms.Api.Management.ViewModels.Document;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Actions;
+using Umbraco.Cms.Core.Models.ContentPublishing;
+using Umbraco.Cms.Core.Security.Authorization;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Services.OperationStatus;
+using Umbraco.Cms.Web.Common.Authorization;
+using Umbraco.Extensions;
+
+namespace Umbraco.Cms.Api.Management.Controllers.Document;
+
+[ApiVersion("1.0")]
+public class PublishDocumentWithDescendantsResultController : DocumentControllerBase
+{
+ private readonly IAuthorizationService _authorizationService;
+ private readonly IContentPublishingService _contentPublishingService;
+
+ public PublishDocumentWithDescendantsResultController(
+ IAuthorizationService authorizationService,
+ IContentPublishingService contentPublishingService)
+ {
+ _authorizationService = authorizationService;
+ _contentPublishingService = contentPublishingService;
+ }
+
+ [HttpGet("{id:guid}/publish-with-descendants/result/{taskId:guid}")]
+ [MapToApiVersion("1.0")]
+ [ProducesResponseType(typeof(PublishWithDescendantsResultModel), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
+ public async Task PublishWithDescendantsResult(CancellationToken cancellationToken, Guid id, Guid taskId)
+ {
+ AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
+ User,
+ ContentPermissionResource.Branch(ActionPublish.ActionLetter, id),
+ AuthorizationPolicies.ContentPermissionByResource);
+
+ if (!authorizationResult.Succeeded)
+ {
+ return Forbidden();
+ }
+
+ // Check if the publishing task has completed, if not, return the status.
+ var isPublishing = await _contentPublishingService.IsPublishingBranchAsync(taskId);
+ if (isPublishing)
+ {
+ return Ok(new PublishWithDescendantsResultModel
+ {
+ TaskId = taskId,
+ IsComplete = false
+ });
+ };
+
+ // If completed, get the result and return the status.
+ Attempt attempt = await _contentPublishingService.GetPublishBranchResultAsync(taskId);
+ return attempt.Success
+ ? Ok(new PublishWithDescendantsResultModel
+ {
+ TaskId = taskId,
+ IsComplete = true
+ })
+ : DocumentPublishingOperationStatusResult(attempt.Status, failedBranchItems: attempt.Result.FailedItems);
+ }
+}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/ReferencedByDocumentRecycleBinController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/ReferencedByDocumentRecycleBinController.cs
new file mode 100644
index 0000000000..2b94fb443f
--- /dev/null
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/ReferencedByDocumentRecycleBinController.cs
@@ -0,0 +1,50 @@
+using Asp.Versioning;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Umbraco.Cms.Api.Common.ViewModels.Pagination;
+using Umbraco.Cms.Api.Management.Factories;
+using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
+
+[ApiVersion("1.0")]
+public class ReferencedByDocumentRecycleBinController : DocumentRecycleBinControllerBase
+{
+ private readonly ITrackedReferencesService _trackedReferencesService;
+ private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
+
+ public ReferencedByDocumentRecycleBinController(
+ IEntityService entityService,
+ IDocumentPresentationFactory documentPresentationFactory,
+ ITrackedReferencesService trackedReferencesService,
+ IRelationTypePresentationFactory relationTypePresentationFactory)
+ : base(entityService, documentPresentationFactory)
+ {
+ _trackedReferencesService = trackedReferencesService;
+ _relationTypePresentationFactory = relationTypePresentationFactory;
+ }
+
+ ///
+ /// Gets a paged list of tracked references for all items in the document recycle bin, so you can see where an item is being used.
+ ///
+ [HttpGet("referenced-by")]
+ [MapToApiVersion("1.0")]
+ [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
+ public async Task>> ReferencedBy(
+ CancellationToken cancellationToken,
+ int skip = 0,
+ int take = 20)
+ {
+ PagedModel relationItems = await _trackedReferencesService.GetPagedRelationsForRecycleBinAsync(UmbracoObjectTypes.Document, skip, take, true);
+
+ var pagedViewModel = new PagedViewModel
+ {
+ Total = relationItems.Total,
+ Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
+ };
+
+ return pagedViewModel;
+ }
+}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs
index 33e451bdc5..cacf862b57 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs
@@ -4,6 +4,7 @@ using Umbraco.Cms.Api.Management.Controllers.Tree;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Api.Management.Services.Entities;
+using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
@@ -33,7 +34,7 @@ public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBa
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
IDocumentPresentationFactory documentPresentationFactory)
- : base(entityService, userStartNodeEntitiesService, dataTypeService)
+ : base(entityService, userStartNodeEntitiesService, dataTypeService)
{
_publicAccessService = publicAccessService;
_appCaches = appCaches;
@@ -52,6 +53,8 @@ public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBa
if (entity is IDocumentEntitySlim documentEntitySlim)
{
responseModel.IsProtected = _publicAccessService.IsProtected(entity.Path);
+ responseModel.Ancestors = EntityService.GetPathKeys(entity, omitSelf: true)
+ .Select(x => new ReferenceByIdModel(x));
responseModel.IsTrashed = entity.Trashed;
responseModel.Id = entity.Key;
responseModel.CreateDate = entity.CreateDate;
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/UpdateNotificationsController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/UpdateNotificationsController.cs
index d02e1456f9..0d504b22a6 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/UpdateNotificationsController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/UpdateNotificationsController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Document;
@@ -35,6 +35,6 @@ public class UpdateNotificationsController : DocumentControllerBase
}
_notificationService.SetNotifications(_backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser, content, updateModel.SubscribedActionIds);
- return await Task.FromResult(Ok());
+ return Ok();
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateCreateDocumentController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateCreateDocumentController.cs
index ecca82286c..7087e119f7 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateCreateDocumentController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateCreateDocumentController.cs
@@ -1,11 +1,14 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.ContentEditing;
+using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
@@ -16,15 +19,32 @@ public class ValidateCreateDocumentController : CreateDocumentControllerBase
{
private readonly IDocumentEditingPresentationFactory _documentEditingPresentationFactory;
private readonly IContentEditingService _contentEditingService;
+ private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
+ [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
public ValidateCreateDocumentController(
IAuthorizationService authorizationService,
IDocumentEditingPresentationFactory documentEditingPresentationFactory,
IContentEditingService contentEditingService)
+ : this(
+ authorizationService,
+ documentEditingPresentationFactory,
+ contentEditingService,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
+ }
+
+ [ActivatorUtilitiesConstructor]
+ public ValidateCreateDocumentController(
+ IAuthorizationService authorizationService,
+ IDocumentEditingPresentationFactory documentEditingPresentationFactory,
+ IContentEditingService contentEditingService,
+ IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
: base(authorizationService)
{
_documentEditingPresentationFactory = documentEditingPresentationFactory;
_contentEditingService = contentEditingService;
+ _backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPost("validate")]
@@ -36,7 +56,10 @@ public class ValidateCreateDocumentController : CreateDocumentControllerBase
=> await HandleRequest(requestModel, async () =>
{
ContentCreateModel model = _documentEditingPresentationFactory.MapCreateModel(requestModel);
- Attempt result = await _contentEditingService.ValidateCreateAsync(model);
+ Attempt result =
+ await _contentEditingService.ValidateCreateAsync(
+ model,
+ CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateUpdateDocumentController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateUpdateDocumentController.cs
index 05f029f582..bf06571c94 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateUpdateDocumentController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/ValidateUpdateDocumentController.cs
@@ -1,58 +1,52 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.ContentEditing;
+using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
-[ApiVersion("1.0")]
[ApiVersion("1.1")]
public class ValidateUpdateDocumentController : UpdateDocumentControllerBase
{
private readonly IContentEditingService _contentEditingService;
private readonly IDocumentEditingPresentationFactory _documentEditingPresentationFactory;
+ private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
+ [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
public ValidateUpdateDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IDocumentEditingPresentationFactory documentEditingPresentationFactory)
+ : this(
+ authorizationService,
+ contentEditingService,
+ documentEditingPresentationFactory,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
+ }
+
+ [ActivatorUtilitiesConstructor]
+ public ValidateUpdateDocumentController(
+ IAuthorizationService authorizationService,
+ IContentEditingService contentEditingService,
+ IDocumentEditingPresentationFactory documentEditingPresentationFactory,
+ IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
: base(authorizationService)
{
_contentEditingService = contentEditingService;
_documentEditingPresentationFactory = documentEditingPresentationFactory;
+ _backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
- [HttpPut("{id:guid}/validate")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
- [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
- [Obsolete("Please use version 1.1 of this API. Will be removed in V16.")]
- public async Task Validate(CancellationToken cancellationToken, Guid id, UpdateDocumentRequestModel requestModel)
- => await HandleRequest(id, requestModel, async () =>
- {
- var validateUpdateDocumentRequestModel = new ValidateUpdateDocumentRequestModel
- {
- Values = requestModel.Values,
- Variants = requestModel.Variants,
- Template = requestModel.Template,
- Cultures = null
- };
-
- ValidateContentUpdateModel model = _documentEditingPresentationFactory.MapValidateUpdateModel(validateUpdateDocumentRequestModel);
- Attempt result = await _contentEditingService.ValidateUpdateAsync(id, model);
-
- return result.Success
- ? Ok()
- : DocumentEditingOperationStatusResult(result.Status, requestModel, result.Result);
- });
-
[HttpPut("{id:guid}/validate")]
[MapToApiVersion("1.1")]
[ProducesResponseType(StatusCodes.Status200OK)]
@@ -62,7 +56,11 @@ public class ValidateUpdateDocumentController : UpdateDocumentControllerBase
=> await HandleRequest(id, requestModel, async () =>
{
ValidateContentUpdateModel model = _documentEditingPresentationFactory.MapValidateUpdateModel(requestModel);
- Attempt result = await _contentEditingService.ValidateUpdateAsync(id, model);
+ Attempt result =
+ await _contentEditingService.ValidateUpdateAsync(
+ id,
+ model,
+ CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/ItemDocumentBlueprintController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/ItemDocumentBlueprintController.cs
index 5694d5b0b9..551f6cc407 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/ItemDocumentBlueprintController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/ItemDocumentBlueprintController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -25,13 +25,13 @@ public class ItemDocumentBlueprintController : DocumentBlueprintItemControllerBa
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task Item(
+ public Task Item(
CancellationToken cancellationToken,
[FromQuery(Name = "id")] HashSet ids)
{
if (ids.Count is 0)
{
- return Ok(Enumerable.Empty());
+ return Task.FromResult(Ok(Enumerable.Empty()));
}
IEnumerable documents = _entityService
@@ -39,6 +39,6 @@ public class ItemDocumentBlueprintController : DocumentBlueprintItemControllerBa
.Select(x => x as IDocumentEntitySlim)
.WhereNotNull();
IEnumerable responseModels = documents.Select(x => _documentPresentationFactory.CreateBlueprintItemResponseModel(x));
- return await Task.FromResult(Ok(responseModels));
+ return Task.FromResult(Ok(responseModels));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs
index f7403cb463..d44bd7ffd0 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs
@@ -23,15 +23,6 @@ public class AllowedChildrenDocumentTypeController : DocumentTypeControllerBase
_umbracoMapper = umbracoMapper;
}
- [NonAction]
- [Obsolete("Use the non obsoleted method instead. Scheduled to be removed in v16")]
- public async Task AllowedChildrenByKey(
- CancellationToken cancellationToken,
- Guid id,
- int skip = 0,
- int take = 100)
- => await AllowedChildrenByKey(cancellationToken, id, null, skip, take);
-
[HttpGet("{id:guid}/allowed-children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs
index c1a4e41a75..74c5c58946 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs
@@ -1,14 +1,9 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.DocumentType;
-using Umbraco.Cms.Core.Configuration.Models;
-using Umbraco.Cms.Core.DependencyInjection;
-using Umbraco.Cms.Core.Features;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.DocumentType;
@@ -19,30 +14,8 @@ public class ConfigurationDocumentTypeController : DocumentTypeControllerBase
{
private readonly IConfigurationPresentationFactory _configurationPresentationFactory;
- [ActivatorUtilitiesConstructor]
public ConfigurationDocumentTypeController(IConfigurationPresentationFactory configurationPresentationFactory)
- {
- _configurationPresentationFactory = configurationPresentationFactory;
- }
-
- [Obsolete("Use the constructor that only accepts IConfigurationPresentationFactory, scheduled for removal in V16")]
- public ConfigurationDocumentTypeController(
- UmbracoFeatures umbracoFeatures,
- IOptionsSnapshot dataTypesSettings,
- IOptionsSnapshot segmentSettings,
- IConfigurationPresentationFactory configurationPresentationFactory)
- : this(configurationPresentationFactory)
- {
- }
-
- [Obsolete("Use the constructor that only accepts IConfigurationPresentationFactory, scheduled for removal in V16")]
- public ConfigurationDocumentTypeController(
- UmbracoFeatures umbracoFeatures,
- IOptionsSnapshot dataTypesSettings,
- IOptionsSnapshot segmentSettings)
- : this(StaticServiceProvider.Instance.GetRequiredService())
- {
- }
+ => _configurationPresentationFactory = configurationPresentationFactory;
[HttpGet("configuration")]
[MapToApiVersion("1.0")]
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/ItemDocumentTypeItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/ItemDocumentTypeItemController.cs
index 55211c7555..a4ed4eaa29 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/ItemDocumentTypeItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/ItemDocumentTypeItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DocumentType.Item;
@@ -23,17 +23,17 @@ public class ItemDocumentTypeItemController : DocumentTypeItemControllerBase
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task Item(
+ public Task Item(
CancellationToken cancellationToken,
[FromQuery(Name = "id")] HashSet ids)
{
if (ids.Count is 0)
{
- return Ok(Enumerable.Empty());
+ return Task.FromResult(Ok(Enumerable.Empty()));
}
IEnumerable contentTypes = _contentTypeService.GetMany(ids);
List responseModels = _mapper.MapEnumerable(contentTypes);
- return await Task.FromResult(Ok(responseModels));
+ return Task.FromResult(Ok(responseModels));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/SearchDocumentTypeItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/SearchDocumentTypeItemController.cs
index 0582c8e3e8..fd9a9217b0 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/SearchDocumentTypeItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/SearchDocumentTypeItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentVersion/RollbackDocumentVersionController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentVersion/RollbackDocumentVersionController.cs
index 1c024f3ef9..64f2f09bb3 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentVersion/RollbackDocumentVersionController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentVersion/RollbackDocumentVersionController.cs
@@ -2,10 +2,8 @@ using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
-using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Security.Authorization;
@@ -23,7 +21,6 @@ public class RollbackDocumentVersionController : DocumentVersionControllerBase
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IAuthorizationService _authorizationService;
- [ActivatorUtilitiesConstructor]
public RollbackDocumentVersionController(
IContentVersionService contentVersionService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
@@ -34,18 +31,6 @@ public class RollbackDocumentVersionController : DocumentVersionControllerBase
_authorizationService = authorizationService;
}
- // TODO (V16): Remove this constructor.
- [Obsolete("Please use the constructor taking all parameters. This constructor will be removed in V16.")]
- public RollbackDocumentVersionController(
- IContentVersionService contentVersionService,
- IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
- : this(
- contentVersionService,
- backOfficeSecurityAccessor,
- StaticServiceProvider.Instance.GetRequiredService())
- {
- }
-
[MapToApiVersion("1.0")]
[HttpPost("{id:guid}/rollback")]
[ProducesResponseType(StatusCodes.Status200OK)]
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs
index 1271c2ab3f..5dc68f4522 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs
@@ -21,10 +21,10 @@ public class GetQueryStepsController : DynamicRootControllerBase
[HttpGet($"steps")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task GetQuerySteps(CancellationToken cancellationToken)
+ public Task GetQuerySteps(CancellationToken cancellationToken)
{
IEnumerable querySteps = _dynamicRootQueryStepCollection.Select(x => x.SupportedDirectionAlias);
- return await Task.FromResult(Ok(querySteps));
+ return Task.FromResult(Ok(querySteps));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/ExecuteActionHealthCheckController.cs b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/ExecuteActionHealthCheckController.cs
index 6f3e5ea933..4a8583f4fd 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/ExecuteActionHealthCheckController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/ExecuteActionHealthCheckController.cs
@@ -63,6 +63,6 @@ public class ExecuteActionHealthCheckController : HealthCheckControllerBase
HealthCheckStatus result = await healthCheck.ExecuteActionAsync(_umbracoMapper.Map(action)!);
- return await Task.FromResult(Ok(_umbracoMapper.Map(result)));
+ return Ok(_umbracoMapper.Map(result));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/AllHealthCheckGroupController.cs b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/AllHealthCheckGroupController.cs
index baaaf467bf..f41f352cc7 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/AllHealthCheckGroupController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/AllHealthCheckGroupController.cs
@@ -31,7 +31,7 @@ public class AllHealthCheckGroupController : HealthCheckGroupControllerBase
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
- public async Task>> All(
+ public Task>> All(
CancellationToken cancellationToken,
int skip = 0,
int take = 100)
@@ -46,6 +46,6 @@ public class AllHealthCheckGroupController : HealthCheckGroupControllerBase
Items = _umbracoMapper.MapEnumerable, HealthCheckGroupResponseModel>(groups.Skip(skip).Take(take))
};
- return await Task.FromResult(Ok(viewModel));
+ return Task.FromResult>>(Ok(viewModel));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/ByNameHealthCheckGroupController.cs b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/ByNameHealthCheckGroupController.cs
index 1aa97c6249..6ffa173e9b 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/ByNameHealthCheckGroupController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/ByNameHealthCheckGroupController.cs
@@ -31,7 +31,7 @@ public class ByNameHealthCheckGroupController : HealthCheckGroupControllerBase
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(HealthCheckGroupPresentationModel), StatusCodes.Status200OK)]
- public async Task ByName(
+ public Task ByName(
CancellationToken cancellationToken,
string name)
{
@@ -42,9 +42,9 @@ public class ByNameHealthCheckGroupController : HealthCheckGroupControllerBase
if (group is null)
{
- return HealthCheckGroupNotFound();
+ return Task.FromResult(HealthCheckGroupNotFound());
}
- return await Task.FromResult(Ok(_umbracoMapper.Map(group)));
+ return Task.FromResult(Ok(_umbracoMapper.Map(group)));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Help/GetHelpController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Help/GetHelpController.cs
index 1c0ea568a1..e2227409b2 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Help/GetHelpController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Help/GetHelpController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
@@ -82,6 +82,5 @@ public class GetHelpController : HelpControllerBase
return Ok(PagedViewModel.Empty());
}
- private bool IsAllowedUrl(string? url) =>
- _helpPageSettings.HelpPageUrlAllowList is null || _helpPageSettings.HelpPageUrlAllowList.Contains(url);
+ private bool IsAllowedUrl(string? url) => url is null || _helpPageSettings.HelpPageUrlAllowList.Contains(url);
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/DetailsIndexerController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/DetailsIndexerController.cs
index a6d8a7c407..0eee31be10 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/DetailsIndexerController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/DetailsIndexerController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Examine;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -34,11 +34,11 @@ public class DetailsIndexerController : IndexerControllerBase
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(IndexResponseModel), StatusCodes.Status200OK)]
- public async Task> Details(CancellationToken cancellationToken, string indexName)
+ public Task> Details(CancellationToken cancellationToken, string indexName)
{
if (_examineManager.TryGetIndex(indexName, out IIndex? index))
{
- return await Task.FromResult(_indexPresentationFactory.Create(index!));
+ return Task.FromResult>(_indexPresentationFactory.Create(index));
}
var invalidModelProblem = new ProblemDetails
@@ -49,7 +49,6 @@ public class DetailsIndexerController : IndexerControllerBase
Type = "Error",
};
- return await Task.FromResult(NotFound(invalidModelProblem));
-
+ return Task.FromResult>(NotFound(invalidModelProblem));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs
index 97131adcb9..cba2252991 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs
@@ -36,7 +36,7 @@ public class RebuildIndexerController : IndexerControllerBase
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status409Conflict)]
[ProducesResponseType(StatusCodes.Status200OK)]
- public async Task Rebuild(CancellationToken cancellationToken, string indexName)
+ public Task Rebuild(CancellationToken cancellationToken, string indexName)
{
if (!_examineManager.TryGetIndex(indexName, out IIndex? index))
{
@@ -48,7 +48,7 @@ public class RebuildIndexerController : IndexerControllerBase
Type = "Error",
};
- return await Task.FromResult(NotFound(invalidModelProblem));
+ return Task.FromResult(NotFound(invalidModelProblem));
}
if (!_indexingRebuilderService.CanRebuild(index.Name))
@@ -62,14 +62,14 @@ public class RebuildIndexerController : IndexerControllerBase
Type = "Error",
};
- return await Task.FromResult(BadRequest(invalidModelProblem));
+ return Task.FromResult(BadRequest(invalidModelProblem));
}
_logger.LogInformation("Rebuilding index '{IndexName}'", indexName);
if (_indexingRebuilderService.TryRebuild(index, indexName))
{
- return await Task.FromResult(Ok());
+ return Task.FromResult(Ok());
}
var problemDetails = new ProblemDetails
@@ -80,6 +80,6 @@ public class RebuildIndexerController : IndexerControllerBase
Type = "Error",
};
- return await Task.FromResult(Conflict(problemDetails));
+ return Task.FromResult(Conflict(problemDetails));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/AllSinkLevelLogViewerController.cs b/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/AllSinkLevelLogViewerController.cs
index f2ec9e034f..e3bd052922 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/AllSinkLevelLogViewerController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/AllSinkLevelLogViewerController.cs
@@ -30,7 +30,7 @@ public class AllSinkLevelLogViewerController : LogViewerControllerBase
[HttpGet("level")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
- public async Task>> AllLogLevels(
+ public Task>> AllLogLevels(
CancellationToken cancellationToken,
int skip = 0,
int take = 100)
@@ -45,6 +45,6 @@ public class AllSinkLevelLogViewerController : LogViewerControllerBase
Items = _umbracoMapper.MapEnumerable, LoggerResponseModel>(logLevels.Skip(skip).Take(take))
};
- return await Task.FromResult(Ok(viewModel));
+ return Task.FromResult>>(Ok(viewModel));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs
index 6a37c2ad40..ba6eb5c8b3 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs
@@ -1,12 +1,10 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Media.Collection;
using Umbraco.Cms.Core;
-using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
@@ -22,20 +20,6 @@ public class ByKeyMediaCollectionController : MediaCollectionControllerBase
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IMediaCollectionPresentationFactory _mediaCollectionPresentationFactory;
- [Obsolete("Please use the constructor taking all parameters.")]
- public ByKeyMediaCollectionController(
- IMediaListViewService mediaListViewService,
- IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
- IUmbracoMapper mapper)
- : this(
- mediaListViewService,
- backOfficeSecurityAccessor,
- mapper,
- StaticServiceProvider.Instance.GetRequiredService())
- {
- }
-
- [ActivatorUtilitiesConstructor]
public ByKeyMediaCollectionController(
IMediaListViewService mediaListViewService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/ConfigurationMediaController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/ConfigurationMediaController.cs
index 0793dd64d3..9d61eac439 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Media/ConfigurationMediaController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/ConfigurationMediaController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -7,6 +7,7 @@ using Umbraco.Cms.Api.Management.ViewModels.Media;
namespace Umbraco.Cms.Api.Management.Controllers.Media;
[ApiVersion("1.0")]
+[Obsolete("No longer used. Scheduled for removal in Umbraco 18.")]
public class ConfigurationMediaController : MediaControllerBase
{
private readonly IConfigurationPresentationFactory _configurationPresentationFactory;
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/ItemMediaItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/ItemMediaItemController.cs
index ddea5cfbcb..7bab65c3ca 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/ItemMediaItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/ItemMediaItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -25,13 +25,13 @@ public class ItemMediaItemController : MediaItemControllerBase
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task Item(
+ public Task Item(
CancellationToken cancellationToken,
[FromQuery(Name = "id")] HashSet ids)
{
if (ids.Count is 0)
{
- return Ok(Enumerable.Empty());
+ return Task.FromResult(Ok(Enumerable.Empty()));
}
IEnumerable media = _entityService
@@ -39,6 +39,6 @@ public class ItemMediaItemController : MediaItemControllerBase
.OfType();
IEnumerable responseModels = media.Select(_mediaPresentationFactory.CreateItemResponseModel);
- return await Task.FromResult(Ok(responseModels));
+ return Task.FromResult(Ok(responseModels));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs
index 6db5950179..b5da421abe 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -23,32 +23,21 @@ public class SearchMediaItemController : MediaItemControllerBase
[NonAction]
[Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
- public async Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
- => await SearchFromParent(cancellationToken, query, skip, take, null);
-
- [NonAction]
- [Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
- [ProducesResponseType(typeof(PagedModel), StatusCodes.Status200OK)]
- public async Task SearchFromParent(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null)
- => await SearchFromParentWithAllowedTypes(cancellationToken, query, skip, take, parentId);
-
- [NonAction]
- [Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
- public async Task SearchFromParentWithAllowedTypes(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null, [FromQuery]IEnumerable? allowedMediaTypes = null)
- => await SearchFromParentWithAllowedTypes(cancellationToken, query, null, skip, take, parentId);
+ public Task SearchFromParentWithAllowedTypes(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null, [FromQuery]IEnumerable? allowedMediaTypes = null)
+ => SearchFromParentWithAllowedTypes(cancellationToken, query, null, skip, take, parentId);
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel), StatusCodes.Status200OK)]
public async Task SearchFromParentWithAllowedTypes(CancellationToken cancellationToken, string query, bool? trashed = null, int skip = 0, int take = 100, Guid? parentId = null, [FromQuery]IEnumerable? allowedMediaTypes = null)
{
- PagedModel searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Media, query, parentId, allowedMediaTypes, trashed, skip, take);
+ PagedModel searchResult = await _indexedEntitySearchService.SearchAsync(UmbracoObjectTypes.Media, query, parentId, allowedMediaTypes, trashed, skip, take);
var result = new PagedModel
{
Items = searchResult.Items.OfType().Select(_mediaPresentationFactory.CreateItemResponseModel),
Total = searchResult.Total,
};
- return await Task.FromResult(Ok(result));
+ return Ok(result);
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaUrlController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaUrlController.cs
index d967bd9435..1db1a3c1be 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaUrlController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaUrlController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -25,10 +25,10 @@ public class MediaUrlController : MediaControllerBase
[MapToApiVersion("1.0")]
[HttpGet("urls")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task GetUrls([FromQuery(Name = "id")] HashSet ids)
+ public Task GetUrls([FromQuery(Name = "id")] HashSet ids)
{
IEnumerable items = _mediaService.GetByIds(ids);
- return await Task.FromResult(Ok(_mediaUrlFactory.CreateUrlSets(items)));
+ return Task.FromResult(Ok(_mediaUrlFactory.CreateUrlSets(items)));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/ReferencedByMediaRecycleBinController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/ReferencedByMediaRecycleBinController.cs
new file mode 100644
index 0000000000..a3c72184d7
--- /dev/null
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/ReferencedByMediaRecycleBinController.cs
@@ -0,0 +1,50 @@
+using Asp.Versioning;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Umbraco.Cms.Api.Common.ViewModels.Pagination;
+using Umbraco.Cms.Api.Management.Factories;
+using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Api.Management.Controllers.Media.RecycleBin;
+
+[ApiVersion("1.0")]
+public class ReferencedByMediaRecycleBinController : MediaRecycleBinControllerBase
+{
+ private readonly ITrackedReferencesService _trackedReferencesService;
+ private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
+
+ public ReferencedByMediaRecycleBinController(
+ IEntityService entityService,
+ IMediaPresentationFactory mediaPresentationFactory,
+ ITrackedReferencesService trackedReferencesService,
+ IRelationTypePresentationFactory relationTypePresentationFactory)
+ : base(entityService, mediaPresentationFactory)
+ {
+ _trackedReferencesService = trackedReferencesService;
+ _relationTypePresentationFactory = relationTypePresentationFactory;
+ }
+
+ ///
+ /// Gets a paged list of tracked references for all items in the media recycle bin, so you can see where an item is being used.
+ ///
+ [HttpGet("referenced-by")]
+ [MapToApiVersion("1.0")]
+ [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
+ public async Task>> ReferencedBy(
+ CancellationToken cancellationToken,
+ int skip = 0,
+ int take = 20)
+ {
+ PagedModel relationItems = await _trackedReferencesService.GetPagedRelationsForRecycleBinAsync(UmbracoObjectTypes.Media, skip, take, true);
+
+ var pagedViewModel = new PagedViewModel
+ {
+ Total = relationItems.Total,
+ Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
+ };
+
+ return pagedViewModel;
+ }
+}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs
index 71ee63d6e3..1981332c68 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs
@@ -23,15 +23,6 @@ public class AllowedChildrenMediaTypeController : MediaTypeControllerBase
_umbracoMapper = umbracoMapper;
}
- [NonAction]
- [Obsolete("Use the non obsoleted method instead. Scheduled for removal in Umbraco 16.")]
- public async Task AllowedChildrenByKey(
- CancellationToken cancellationToken,
- Guid id,
- int skip = 0,
- int take = 100)
- => await AllowedChildrenByKey(cancellationToken, id, null, skip, take);
-
[HttpGet("{id:guid}/allowed-children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/ByKeyMediaTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/ByKeyMediaTypeController.cs
index ec3d955b2f..75a32569bd 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/ByKeyMediaTypeController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/ByKeyMediaTypeController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.MediaType;
@@ -34,6 +34,6 @@ public class ByKeyMediaTypeController : MediaTypeControllerBase
}
MediaTypeResponseModel model = _umbracoMapper.Map(mediaType)!;
- return await Task.FromResult(Ok(model));
+ return Ok(model);
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/ItemMediaTypeItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/ItemMediaTypeItemController.cs
index 14bcff0e51..92133d2808 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/ItemMediaTypeItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/ItemMediaTypeItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.MediaType.Item;
@@ -23,17 +23,17 @@ public class ItemMediaTypeItemController : MediaTypeItemControllerBase
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task Item(
+ public Task Item(
CancellationToken cancellationToken,
[FromQuery(Name = "id")] HashSet ids)
{
if (ids.Count is 0)
{
- return Ok(Enumerable.Empty());
+ return Task.FromResult(Ok(Enumerable.Empty()));
}
IEnumerable mediaTypes = _mediaTypeService.GetMany(ids);
List responseModels = _mapper.MapEnumerable(mediaTypes);
- return await Task.FromResult(Ok(responseModels));
+ return Task.FromResult(Ok(responseModels));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/SearchMediaTypeItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/SearchMediaTypeItemController.cs
index 475087766f..a6fbade1c7 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/SearchMediaTypeItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/SearchMediaTypeItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.MediaType.Item;
@@ -27,12 +27,12 @@ public class SearchMediaTypeItemController : MediaTypeItemControllerBase
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel), StatusCodes.Status200OK)]
- public async Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
+ public Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
{
PagedModel searchResult = _entitySearchService.Search(UmbracoObjectTypes.MediaType, query, skip, take);
if (searchResult.Items.Any() is false)
{
- return await Task.FromResult(Ok(new PagedModel { Total = searchResult.Total }));
+ return Task.FromResult(Ok(new PagedModel { Total = searchResult.Total }));
}
IEnumerable mediaTypes = _mediaTypeService.GetMany(searchResult.Items.Select(item => item.Key).ToArray().EmptyNull());
@@ -42,6 +42,6 @@ public class SearchMediaTypeItemController : MediaTypeItemControllerBase
Total = searchResult.Total
};
- return Ok(result);
+ return Task.FromResult(Ok(result));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/ItemMemberItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/ItemMemberItemController.cs
index eb81efed18..8e2e73538c 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/ItemMemberItemController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/ItemMemberItemController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
@@ -25,13 +25,13 @@ public class ItemMemberItemController : MemberItemControllerBase
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
- public async Task Item(
+ public Task Item(
CancellationToken cancellationToken,
[FromQuery(Name = "id")] HashSet ids)
{
if (ids.Count is 0)
{
- return Ok(Enumerable.Empty());
+ return Task.FromResult(Ok(Enumerable.Empty()));
}
IEnumerable members = _entityService
@@ -39,6 +39,6 @@ public class ItemMemberItemController : MemberItemControllerBase
.OfType();
IEnumerable