A little Monday cleanup (#13823)

* Introduce root key constant

* Do not enforce ProblemDetails on every non-success response from the API + remove invalid NotFoundResult response types from various endpoints

* Update OpenAPI JSON contract to reflect the new NotFound results
This commit is contained in:
Kenn Jacobsen
2023-02-13 15:16:21 +01:00
committed by GitHub
parent 233be8dc8f
commit 620a673fa3
10 changed files with 59 additions and 292 deletions

View File

@@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace Umbraco.Cms.Api.Common.Configuration;
public class ConfigureApiBehaviorOptions : IConfigureOptions<ApiBehaviorOptions>
{
public void Configure(ApiBehaviorOptions options) =>
// disable ProblemDetails as default result type for every non-success response (i.e. 404)
// - see https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.apibehavioroptions.suppressmapclienterrors
options.SuppressMapClientErrors = true;
}

View File

@@ -5,6 +5,7 @@ using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
@@ -25,7 +26,7 @@ public class AllDictionaryController : DictionaryControllerBase
public async Task<ActionResult<PagedViewModel<DictionaryOverviewViewModel>>> All(int skip = 0, int take = 100)
{
// unfortunately we can't paginate here...we'll have to get all and paginate in memory
IDictionaryItem[] items = (await _dictionaryItemService.GetDescendantsAsync(null)).ToArray();
IDictionaryItem[] items = (await _dictionaryItemService.GetDescendantsAsync(Constants.System.RootKey)).ToArray();
var model = new PagedViewModel<DictionaryOverviewViewModel>
{
Total = items.Length,

View File

@@ -23,7 +23,7 @@ public class ExportDictionaryController : DictionaryControllerBase
[HttpGet("{key:guid}/export")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Export(Guid key, bool includeChildren = false)
{
IDictionaryItem? dictionaryItem = await _dictionaryItemService.GetAsync(key);

View File

@@ -29,7 +29,7 @@ public class UpdateLanguageController : LanguageControllerBase
[HttpPut($"{{{nameof(isoCode)}}}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> Update(string isoCode, LanguageUpdateModel languageUpdateModel)

View File

@@ -25,7 +25,7 @@ public class ByNameSavedSearchLogViewerController : SavedSearchLogViewerControll
/// <returns>The saved log search or not found result.</returns>
[HttpGet("{name}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(SavedLogSearchViewModel), StatusCodes.Status200OK)]
public async Task<ActionResult<SavedLogSearchViewModel>> ByName(string name)
{

View File

@@ -20,7 +20,7 @@ public class DeleteSavedSearchLogViewerController : SavedSearchLogViewerControll
/// <returns>The result of the deletion.</returns>
[HttpDelete("{name}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> Delete(string name)
{

View File

@@ -21,7 +21,7 @@ public class ByIdRelationController : RelationControllerBase
[HttpGet("{id:int}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(RelationViewModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult> ById(int id)
{
IRelation? relation = _relationService.GetById(id);

View File

@@ -1,6 +1,3 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Composing;
@@ -9,7 +6,6 @@ using Umbraco.Cms.Api.Common.Configuration;
using Umbraco.Cms.Api.Common.DependencyInjection;
using Umbraco.Cms.Api.Management.DependencyInjection;
using Umbraco.Cms.Api.Management.Serialization;
using Umbraco.Cms.Infrastructure.Serialization;
using Umbraco.Cms.Web.Common.ApplicationBuilder;
using Umbraco.New.Cms.Core.Models.Configuration;
@@ -45,6 +41,7 @@ public class ManagementApiComposer : IComposer
services
.ConfigureOptions<ConfigureMvcOptions>()
.ConfigureOptions<ConfigureApiBehaviorOptions>()
.Configure<UmbracoPipelineOptions>(options =>
{
options.AddFilter(new UmbracoPipelineFilter(

View File

@@ -80,14 +80,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -125,14 +118,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -167,14 +153,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -222,14 +201,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -269,14 +241,7 @@
"description": "Created"
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -316,14 +281,7 @@
"description": "Success"
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -364,14 +322,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -435,14 +386,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -467,14 +411,7 @@
"description": "Success"
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -512,14 +449,7 @@
"description": "Success"
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -733,14 +663,7 @@
"description": "Created"
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
},
"400": {
"description": "Bad Request",
@@ -798,14 +721,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -840,14 +756,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -895,14 +804,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -945,14 +847,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResultModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -1002,14 +897,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -1048,14 +936,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -1488,14 +1369,7 @@
],
"responses": {
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Unauthorized"
},
"200": {
"description": "Success",
@@ -1538,14 +1412,7 @@
],
"responses": {
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Unauthorized"
},
"200": {
"description": "Success",
@@ -1791,14 +1658,7 @@
],
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
},
"200": {
"description": "Success",
@@ -1835,14 +1695,7 @@
],
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
},
"200": {
"description": "Success",
@@ -2285,14 +2138,7 @@
},
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
},
"400": {
"description": "Bad Request",
@@ -2328,14 +2174,7 @@
],
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
},
"200": {
"description": "Success",
@@ -2424,14 +2263,7 @@
},
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResultModel"
}
}
}
"description": "Not Found"
},
"400": {
"description": "Bad Request",
@@ -2768,14 +2600,7 @@
],
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResultModel"
}
}
}
"description": "Not Found"
},
"200": {
"description": "Success",
@@ -2810,14 +2635,7 @@
],
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResultModel"
}
}
}
"description": "Not Found"
},
"200": {
"description": "Success"
@@ -3049,14 +2867,7 @@
],
"responses": {
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Unauthorized"
},
"200": {
"description": "Success",
@@ -3099,14 +2910,7 @@
],
"responses": {
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Unauthorized"
},
"200": {
"description": "Success",
@@ -4037,14 +3841,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResultModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -4805,14 +4602,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -4850,14 +4640,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -4892,14 +4675,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
},
@@ -4947,14 +4723,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -5042,14 +4811,7 @@
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsModel"
}
}
}
"description": "Not Found"
}
}
}
@@ -7854,16 +7616,6 @@
}
}
},
"NotFoundResultModel": {
"type": "object",
"properties": {
"statusCode": {
"type": "integer",
"format": "int32"
}
},
"additionalProperties": false
},
"OkResultModel": {
"type": "object",
"properties": {

View File

@@ -18,6 +18,11 @@ public static partial class Constants
/// <remarks>Use this instead of re-creating the string everywhere.</remarks>
public const string RootString = "-1";
/// <summary>
/// The GUID identifier for global system root node.
/// </summary>
public static readonly Guid? RootKey = null;
/// <summary>
/// The integer identifier for content's recycle bin.
/// </summary>