diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs index 845104719e..c1f08f5a85 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs @@ -6,6 +6,7 @@ using System.Net.Mime; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; @@ -606,14 +607,16 @@ namespace Umbraco.Web.BackOffice.Controllers return notificationModel; } - private void EnsureUniqueName(string name, IContent content, string modelName) + private bool EnsureUniqueName(string name, IContent content, string modelName) { var existing = _contentService.GetBlueprintsForContentTypes(content.ContentTypeId); if (existing.Any(x => x.Name == name && x.Id != content.Id)) { ModelState.AddModelError(modelName, _localizedTextService.Localize("blueprints/duplicateBlueprintMessage")); - throw HttpResponseException.CreateValidationErrorResponse(ModelState); + return false; } + + return true; } /// @@ -627,7 +630,10 @@ namespace Umbraco.Web.BackOffice.Controllers contentItem, content => { - EnsureUniqueName(content.Name, content, "Name"); + if (!EnsureUniqueName(content.Name, content, "Name")) + { + return OperationResult.Cancel(new EventMessages()); + } _contentService.SaveBlueprint(contentItem.PersistedContent, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id); @@ -839,9 +845,15 @@ namespace Umbraco.Web.BackOffice.Controllers v.Notifications.AddRange(n.Notifications); } - //lastly, if it is not valid, add the model state to the outgoing object and throw a 400 HandleInvalidModelState(display, cultureForInvariantErrors); + //lastly, if it is not valid, add the model state to the outgoing object and throw a 400 + if (!ModelState.IsValid) + { + display.Errors = ModelState.ToErrorDictionary(); + return new ValidationErrorResult(display); + } + if (wasCancelled) { AddCancelMessage(display); @@ -1915,9 +1927,6 @@ namespace Umbraco.Web.BackOffice.Controllers AddVariantValidationError(culture, segment, "speechBubbles/contentCultureValidationError"); } } - - base.HandleInvalidModelState(display); - } /// diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs index 965059b83f..f5934a9583 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs @@ -282,7 +282,8 @@ namespace Umbraco.Web.BackOffice.Controllers if (ModelState.IsValid == false) { - throw CreateModelStateValidationException(ctId, contentTypeSave, ct); + var err = CreateModelStateValidationEror(ctId, contentTypeSave, ct); + return new ValidationErrorResult(err); } //filter out empty properties @@ -304,11 +305,11 @@ namespace Umbraco.Web.BackOffice.Controllers catch (Exception ex) { var responseEx = CreateInvalidCompositionResponseException(ex, contentTypeSave, ct, ctId); - if (responseEx != null) throw responseEx; + if (responseEx != null) return new ValidationErrorResult(responseEx); } var exResult = CreateCompositionValidationExceptionIfInvalid(contentTypeSave, ct); - if (exResult != null) throw exResult; + if (exResult != null) return new ValidationErrorResult(exResult); saveContentType(ct); @@ -344,11 +345,14 @@ namespace Umbraco.Web.BackOffice.Controllers catch (Exception ex) { var responseEx = CreateInvalidCompositionResponseException(ex, contentTypeSave, ct, ctId); - throw responseEx ?? ex; + if (responseEx is null) + throw ex; + + return new ValidationErrorResult(responseEx); } var exResult = CreateCompositionValidationExceptionIfInvalid(contentTypeSave, newCt); - if (exResult != null) throw exResult; + if (exResult != null) return new ValidationErrorResult(exResult); //set id to null to ensure its handled as a new type contentTypeSave.Id = null; @@ -472,7 +476,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// /// - private HttpResponseException CreateCompositionValidationExceptionIfInvalid(TContentTypeSave contentTypeSave, TContentType composition) + private TContentTypeDisplay CreateCompositionValidationExceptionIfInvalid(TContentTypeSave contentTypeSave, TContentType composition) where TContentTypeSave : ContentTypeSave where TPropertyType : PropertyTypeBasic where TContentTypeDisplay : ContentTypeCompositionDisplay @@ -490,7 +494,7 @@ namespace Umbraco.Web.BackOffice.Controllers //map the 'save' data on top display = UmbracoMapper.Map(contentTypeSave, display); display.Errors = ModelState.ToErrorDictionary(); - throw HttpResponseException.CreateValidationErrorResponse(display); + return display; } return null; } @@ -539,7 +543,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// /// - private HttpResponseException CreateInvalidCompositionResponseException( + private TContentTypeDisplay CreateInvalidCompositionResponseException( Exception ex, TContentTypeSave contentTypeSave, TContentType ct, int ctId) where TContentTypeDisplay : ContentTypeCompositionDisplay where TContentTypeSave : ContentTypeSave @@ -557,7 +561,7 @@ namespace Umbraco.Web.BackOffice.Controllers if (invalidCompositionException != null) { AddCompositionValidationErrors(contentTypeSave, invalidCompositionException.PropertyTypeAliases); - return CreateModelStateValidationException(ctId, contentTypeSave, ct); + return CreateModelStateValidationEror(ctId, contentTypeSave, ct); } return null; } @@ -570,7 +574,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// /// - private HttpResponseException CreateModelStateValidationException(int ctId, TContentTypeSave contentTypeSave, TContentType ct) + private TContentTypeDisplay CreateModelStateValidationEror(int ctId, TContentTypeSave contentTypeSave, TContentType ct) where TContentTypeDisplay : ContentTypeCompositionDisplay where TContentTypeSave : ContentTypeSave { @@ -589,7 +593,7 @@ namespace Umbraco.Web.BackOffice.Controllers } forDisplay.Errors = ModelState.ToErrorDictionary(); - return HttpResponseException.CreateValidationErrorResponse(forDisplay); + return forDisplay; } } }