diff --git a/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs b/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs index c18cb98509..725e299193 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs @@ -92,7 +92,7 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers { var url = PrepareUrl(x => x.PostSave(null)); - var contentService = GetRequiredService(); + var contentTypeService = GetRequiredService(); var contentType = new ContentTypeBuilder() @@ -108,6 +108,7 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers contentTypeService.Save(contentType); + var contentService = GetRequiredService(); var content = new ContentBuilder() .WithId(0) .WithName("Invariant") @@ -139,8 +140,12 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers var body = await response.Content.ReadAsStringAsync(); - Assert.AreEqual(HttpStatusCode.NotFound, response.StatusCode); - Assert.AreEqual(")]}',\n{\"message\":\"No variants flagged for saving\"}", body); + Assert.Multiple(() => + { + Assert.AreEqual(HttpStatusCode.NotFound, response.StatusCode); + Assert.AreEqual(")]}',\n{\"message\":\"No variants flagged for saving\"}", body); + }); + } /// @@ -253,9 +258,13 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, body); - var display = JsonConvert.DeserializeObject(body); - Assert.AreEqual(1, display.Variants.Count()); + Assert.Multiple(() => + { + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, body); + var display = JsonConvert.DeserializeObject(body); + Assert.AreEqual(1, display.Variants.Count()); + }); + } [Test] @@ -307,11 +316,13 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); - Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); - var display = JsonConvert.DeserializeObject(body); - Assert.AreEqual(1, display.Errors.Count()); - Assert.IsTrue(display.Errors.ContainsKey("Variants[0].Name")); - //ModelState":{"Variants[0].Name":["Required"]} + Assert.Multiple(() => + { + Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); + var display = JsonConvert.DeserializeObject(body); + Assert.AreEqual(1, display.Errors.Count(), string.Join(",", display.Errors)); + CollectionAssert.Contains(display.Errors.Keys, "Variants[0].Name"); + }); } [Test] @@ -358,15 +369,18 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers }); // Assert - var body = await response.Content.ReadAsStringAsync(); - body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); - Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); - var display = JsonConvert.DeserializeObject(body); - Assert.AreEqual(2, display.Errors.Count()); - Assert.IsTrue(display.Errors.ContainsKey("Variants[0].Name")); - Assert.IsTrue(display.Errors.ContainsKey("_content_variant_en-US_null_")); + Assert.Multiple(() => + { + Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); + var display = JsonConvert.DeserializeObject(body); + Assert.AreEqual(2, display.Errors.Count()); + CollectionAssert.Contains(display.Errors.Keys, "Variants[0].Name"); + CollectionAssert.Contains(display.Errors.Keys, "_content_variant_en-US_null_"); + }); + + } diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index a0d3d65e94..d366ea49ee 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -64,7 +64,8 @@ namespace Umbraco.Tests.Integration.TestServerTest [TearDown] public void TearDown() { - Client.Dispose(); + + Factory.Dispose(); if (Current.IsInitialized) { diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs index 82fe9ef928..c5ca1d0815 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeNotificationsController.cs @@ -1,4 +1,5 @@ -using Umbraco.Web.WebApi.Filters; +using Umbraco.Web.BackOffice.Filters; +using Umbraco.Web.WebApi.Filters; namespace Umbraco.Web.BackOffice.Controllers { @@ -7,7 +8,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// resulting message is INotificationModel in which case it will append any Event Messages /// currently in the request. /// - //[PrefixlessBodyModelValidator] // TODO implement this!! + [PrefixlessBodyModelValidator] [AppendCurrentEventMessagesAttribute] public abstract class BackOfficeNotificationsController : UmbracoAuthorizedJsonController { diff --git a/src/Umbraco.Web.BackOffice/Filters/PrefixlessBodyModelValidatorAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/PrefixlessBodyModelValidatorAttribute.cs new file mode 100644 index 0000000000..a19655f8ce --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Filters/PrefixlessBodyModelValidatorAttribute.cs @@ -0,0 +1,52 @@ +using System; +using System.Linq; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace Umbraco.Web.BackOffice.Filters +{ + public class PrefixlessBodyModelValidatorAttribute : TypeFilterAttribute + { + public PrefixlessBodyModelValidatorAttribute() : base(typeof(PrefixlessBodyModelValidatorFilter)) + { + } + + private class PrefixlessBodyModelValidatorFilter : IActionFilter + { + public void OnActionExecuted(ActionExecutedContext context) + { + } + + public void OnActionExecuting(ActionExecutingContext context) + { + if (context.ModelState.IsValid) return; + + //Remove prefix from errors + + + foreach (var modelStateItem in context.ModelState) + { + foreach (var prefix in context.ActionArguments.Keys) + { + if (modelStateItem.Key.StartsWith(prefix)) + { + if (modelStateItem.Value.Errors.Any()) + { + + var newKey = modelStateItem.Key.Substring(prefix.Length).TrimStart('.'); + foreach (var valueError in modelStateItem.Value.Errors) + { + context.ModelState.TryAddModelError(newKey, valueError.ErrorMessage); + } + context.ModelState.Remove(modelStateItem.Key); + + } + } + } + + } + } + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Validation/PrefixlessBodyModelValidator.cs b/src/Umbraco.Web.BackOffice/Validation/PrefixlessBodyModelValidator.cs deleted file mode 100644 index d22b044e51..0000000000 --- a/src/Umbraco.Web.BackOffice/Validation/PrefixlessBodyModelValidator.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ModelBinding; -using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; - -namespace Umbraco.Web.BackOffice.Validation -{ - public class PrefixlessBodyModelValidator : ObjectModelValidator - { - public PrefixlessBodyModelValidator(IModelMetadataProvider modelMetadataProvider, IList validatorProviders) : - base(modelMetadataProvider, validatorProviders) - { - - } - - public override ValidationVisitor GetValidationVisitor(ActionContext actionContext, IModelValidatorProvider validatorProvider, - ValidatorCache validatorCache, IModelMetadataProvider metadataProvider, ValidationStateDictionary validationState) - { - var visitor = new PrefixlessValidationVisitor( - actionContext, - validatorProvider, - validatorCache, - metadataProvider, - validationState); - - return visitor; - } - - private class PrefixlessValidationVisitor : ValidationVisitor - { - public PrefixlessValidationVisitor(ActionContext actionContext, IModelValidatorProvider validatorProvider, ValidatorCache validatorCache, IModelMetadataProvider metadataProvider, ValidationStateDictionary validationState) - : base(actionContext, validatorProvider, validatorCache, metadataProvider, validationState) { - - } - - public override bool Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel) - { - return base.Validate(metadata, string.Empty, model, alwaysValidateAtTopLevel); - } - } - } - - -}