diff --git a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/ApiBehaviorApiDescriptionProvider.cs b/src/Microsoft.AspNetCore.Mvc.ApiExplorer/ApiBehaviorApiDescriptionProvider.cs
deleted file mode 100644
index 0296189e6b..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/ApiBehaviorApiDescriptionProvider.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc.Abstractions;
-using Microsoft.AspNetCore.Mvc.Internal;
-using Microsoft.AspNetCore.Mvc.ModelBinding;
-
-namespace Microsoft.AspNetCore.Mvc.ApiExplorer
-{
- public class ApiBehaviorApiDescriptionProvider : IApiDescriptionProvider
- {
- private readonly IModelMetadataProvider _modelMetadaProvider;
-
- public ApiBehaviorApiDescriptionProvider(IModelMetadataProvider modelMetadataProvider)
- {
- _modelMetadaProvider = modelMetadataProvider;
- }
-
- ///
- /// The order is set to execute after the default provider.
- ///
- public int Order => -1000 + 10;
-
- public void OnProvidersExecuted(ApiDescriptionProviderContext context)
- {
- }
-
- public void OnProvidersExecuting(ApiDescriptionProviderContext context)
- {
- foreach (var description in context.Results)
- {
- if (!AppliesTo(description))
- {
- continue;
- }
-
- foreach (var responseType in CreateProblemResponseTypes(description))
- {
- description.SupportedResponseTypes.Add(responseType);
- }
- }
- }
-
- public bool AppliesTo(ApiDescription description)
- {
- return description.ActionDescriptor.FilterDescriptors.Any(f => f.Filter is IApiBehaviorMetadata);
- }
-
- // Check if the parameter is named "id" (e.g. int id) or ends in Id (e.g. personId)
- public bool IsIdParameter(ParameterDescriptor parameter)
- {
- if (parameter.Name == null)
- {
- return false;
- }
-
- if (string.Equals("id", parameter.Name, StringComparison.Ordinal))
- {
- return true;
- }
-
- // We're looking for a name ending with Id, but preceded by a lower case letter. This should match
- // the normal PascalCase naming conventions.
- if (parameter.Name.Length >= 3 &&
- parameter.Name.EndsWith("Id", StringComparison.Ordinal) &&
- char.IsLower(parameter.Name, parameter.Name.Length - 3))
- {
- return true;
- }
-
- return false;
- }
-
- public IEnumerable CreateProblemResponseTypes(ApiDescription description)
- {
- if (description.ActionDescriptor.Parameters.Any() || description.ActionDescriptor.BoundProperties.Any())
- {
- // For validation errors.
- yield return CreateProblemResponse(StatusCodes.Status400BadRequest);
-
- if (description.ActionDescriptor.Parameters.Any(p => IsIdParameter(p)))
- {
- yield return CreateProblemResponse(StatusCodes.Status404NotFound);
- }
- }
-
- yield return CreateProblemResponse(statusCode: 0, isDefaultResponse: true);
- }
-
- private ApiResponseType CreateProblemResponse(int statusCode, bool isDefaultResponse = false)
- {
- return new ApiResponseType
- {
- ApiResponseFormats = new List
- {
- new ApiResponseFormat
- {
- MediaType = "application/problem+json",
- },
- new ApiResponseFormat
- {
- MediaType = "application/problem+xml",
- },
- },
- IsDefaultResponse = isDefaultResponse,
- ModelMetadata = _modelMetadaProvider.GetMetadataForType(typeof(ProblemDetails)),
- StatusCode = statusCode,
- Type = typeof(ProblemDetails),
- };
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcCoreBuilderExtensions.cs
index bcf71e8642..0d3b74c378 100644
--- a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcCoreBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcCoreBuilderExtensions.cs
@@ -26,8 +26,6 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddSingleton();
services.TryAddEnumerable(
ServiceDescriptor.Transient());
- services.TryAddEnumerable(
- ServiceDescriptor.Transient());
}
}
}
diff --git a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.Mvc.ApiExplorer/Properties/AssemblyInfo.cs
index 18b9b08433..40008c2f22 100644
--- a/src/Microsoft.AspNetCore.Mvc.ApiExplorer/Properties/AssemblyInfo.cs
+++ b/src/Microsoft.AspNetCore.Mvc.ApiExplorer/Properties/AssemblyInfo.cs
@@ -10,4 +10,5 @@ using System.Runtime.CompilerServices;
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterRouteInfo))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiRequestFormat))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiResponseFormat))]
-[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiResponseType))]
\ No newline at end of file
+[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiResponseType))]
+[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.ApiExplorer.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApiBehaviorOptions.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApiBehaviorOptions.cs
index 65c64586ce..e955f25768 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/ApiBehaviorOptions.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/ApiBehaviorOptions.cs
@@ -18,8 +18,8 @@ namespace Microsoft.AspNetCore.Mvc
/// Delegate invoked on actions annotated with to convert invalid
/// into an
///
- /// By default, the delegate produces a using
- /// as the problem format.
+ /// By default, the delegate produces a that wraps a serialized form
+ /// of .
///
///
public Func InvalidModelStateResponseFactory
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorOptionsSetup.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorOptionsSetup.cs
index 52be8d2e0a..8556f7db56 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorOptionsSetup.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorOptionsSetup.cs
@@ -3,6 +3,7 @@
using System;
using Microsoft.AspNetCore.Mvc.Infrastructure;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Mvc.Internal
@@ -29,16 +30,16 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{
var errorDetails = _errorDescriptionFactory.CreateErrorDescription(
context.ActionDescriptor,
- new ValidationProblemDetails(context.ModelState));
+ context.ModelState);
- return new BadRequestObjectResult(errorDetails)
- {
- ContentTypes =
- {
- "application/problem+json",
- "application/problem+xml",
- },
- };
+ var result = (errorDetails is ModelStateDictionary modelState) ?
+ new BadRequestObjectResult(modelState) :
+ new BadRequestObjectResult(errorDetails);
+
+ result.ContentTypes.Add("application/problem+json");
+ result.ContentTypes.Add("application/problem+json");
+
+ return result;
}
}
}
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs
index 443a6a59b1..2c4d96c4aa 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Properties/Resources.Designer.cs
@@ -1327,7 +1327,7 @@ namespace Microsoft.AspNetCore.Mvc.Core
=> string.Format(CultureInfo.CurrentCulture, GetString("UrlHelper_RelativePagePathIsNotSupported"), p0);
///
- /// One or more validation errors occured.
+ /// One or more validation errors occurred.
///
internal static string ValidationProblemDescription_Title
{
@@ -1335,7 +1335,7 @@ namespace Microsoft.AspNetCore.Mvc.Core
}
///
- /// One or more validation errors occured.
+ /// One or more validation errors occurred.
///
internal static string FormatValidationProblemDescription_Title()
=> GetString("ValidationProblemDescription_Title");
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx b/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx
index 4a0fd9fd1a..a607e28eff 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Resources.resx
@@ -413,7 +413,7 @@
The relative page path '{0}' can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.
- One or more validation errors occured.
+ One or more validation errors occurred.
Action methods on controllers annotated with {0} must have an attribute route.
diff --git a/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Properties/Resources.Designer.cs
index 9396dad37e..94864035dd 100644
--- a/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Properties/Resources.Designer.cs
@@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
=> string.Format(CultureInfo.CurrentCulture, GetString("EnumerableWrapperProvider_InvalidSourceEnumerableOfT"), p0);
///
- /// An error occured while deserializing input data.
+ /// An error occurred while deserializing input data.
///
internal static string ErrorDeserializingInputData
{
@@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
}
///
- /// An error occured while deserializing input data.
+ /// An error occurred while deserializing input data.
///
internal static string FormatErrorDeserializingInputData()
=> GetString("ErrorDeserializingInputData");
diff --git a/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Resources.resx b/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Resources.resx
index b3e8d858f3..b83867ae64 100644
--- a/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Resources.resx
+++ b/src/Microsoft.AspNetCore.Mvc.Formatters.Xml/Resources.resx
@@ -121,7 +121,7 @@
The type must be an interface and must be or derive from '{0}'.
- An error occured while deserializing input data.
+ An error occurred while deserializing input data.
{0} does not recognize '{1}', so instead use '{2}' with '{3}' set to '{4}' for value type property '{5}' on type '{6}'.
diff --git a/test/Microsoft.AspNetCore.Mvc.ApiExplorer.Test/ApiBehaviorApiDescriptionProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.ApiExplorer.Test/ApiBehaviorApiDescriptionProviderTest.cs
deleted file mode 100644
index f5b22d0527..0000000000
--- a/test/Microsoft.AspNetCore.Mvc.ApiExplorer.Test/ApiBehaviorApiDescriptionProviderTest.cs
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.AspNetCore.Mvc.Abstractions;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Microsoft.AspNetCore.Mvc.Internal;
-using Microsoft.AspNetCore.Mvc.ModelBinding;
-using Moq;
-using Xunit;
-
-namespace Microsoft.AspNetCore.Mvc.ApiExplorer
-{
- public class ApiBehaviorApiDescriptionProviderTest
- {
- [Fact]
- public void AppliesTo_ActionWithoutApiBehavior_ReturnsFalse()
- {
- // Arrange
- var action = new ActionDescriptor()
- {
- FilterDescriptors = new List(),
- };
- var description = new ApiDescription()
- {
- ActionDescriptor = action,
- };
-
- var provider = new ApiBehaviorApiDescriptionProvider(new EmptyModelMetadataProvider());
-
- // Act
- var result = provider.AppliesTo(description);
-
- // Assert
- Assert.False(result);
- }
-
- [Fact]
- public void AppliesTo_ActionWithApiBehavior_ReturnsTrue()
- {
- // Arrange
- var action = new ActionDescriptor()
- {
- FilterDescriptors = new List()
- {
- new FilterDescriptor(Mock.Of(), FilterScope.Global),
- }
- };
- var description = new ApiDescription()
- {
- ActionDescriptor = action,
- };
-
- var provider = new ApiBehaviorApiDescriptionProvider(new EmptyModelMetadataProvider());
-
- // Act
- var result = provider.AppliesTo(description);
-
- // Assert
- Assert.True(result);
- }
-
- [Theory]
- [InlineData("id")]
- [InlineData("personId")]
- [InlineData("üId")]
- public void IsIdParameter_ParameterNameMatchesConvention_ReturnsTrue(string name)
- {
- var parameter = new ParameterDescriptor()
- {
- Name = name,
- };
-
- var provider = new ApiBehaviorApiDescriptionProvider(new EmptyModelMetadataProvider());
-
- // Act
- var result = provider.IsIdParameter(parameter);
-
- // Assert
- Assert.True(result);
- }
-
- [Theory]
- [InlineData(null)]
- [InlineData("")]
- [InlineData("i")]
- [InlineData("Id")]
- [InlineData("iD")]
- [InlineData("persoNId")]
- [InlineData("personid")]
- [InlineData("ü Id")]
- [InlineData("ÜId")]
- public void IsIdParameter_ParameterNameDoesNotMatchConvention_ReturnsFalse(string name)
- {
- var parameter = new ParameterDescriptor()
- {
- Name = name,
- };
-
- var provider = new ApiBehaviorApiDescriptionProvider(new EmptyModelMetadataProvider());
-
- // Act
- var result = provider.IsIdParameter(parameter);
-
- // Assert
- Assert.False(result);
- }
-
- [Fact]
- public void CreateProblemResponseTypes_NoParameters_IncludesDefaultResponse()
- {
- // Arrange
- var action = new ActionDescriptor()
- {
- FilterDescriptors = new List()
- {
- new FilterDescriptor(Mock.Of(), FilterScope.Global),
- },
- BoundProperties = new List(),
- Parameters = new List(),
- };
- var description = new ApiDescription()
- {
- ActionDescriptor = action,
- };
-
- var provider = new ApiBehaviorApiDescriptionProvider(new EmptyModelMetadataProvider());
-
- // Act
- var results = provider.CreateProblemResponseTypes(description);
-
- // Assert
- Assert.Collection(
- results.OrderBy(r => r.StatusCode),
- r =>
- {
- Assert.Equal(typeof(ProblemDetails), r.Type);
- Assert.Equal(0, r.StatusCode);
- Assert.True(r.IsDefaultResponse);
- });
- }
-
- [Fact]
- public void CreateProblemResponseTypes_WithBoundProperty_Includes400Response()
- {
- // Arrange
- var action = new ActionDescriptor()
- {
- FilterDescriptors = new List()
- {
- new FilterDescriptor(Mock.Of(), FilterScope.Global),
- },
- BoundProperties = new List()
- {
- new ParameterDescriptor()
- },
- Parameters = new List(),
- };
- var description = new ApiDescription()
- {
- ActionDescriptor = action,
- };
-
- var provider = new ApiBehaviorApiDescriptionProvider(new EmptyModelMetadataProvider());
-
- // Act
- var results = provider.CreateProblemResponseTypes(description);
-
- // Assert
- Assert.Collection(
- results.OrderBy(r => r.StatusCode),
- r =>
- {
- Assert.Equal(typeof(ProblemDetails), r.Type);
- Assert.Equal(0, r.StatusCode);
- Assert.True(r.IsDefaultResponse);
- },
- r =>
- {
- Assert.Equal(typeof(ProblemDetails), r.Type);
- Assert.Equal(400, r.StatusCode);
- Assert.False(r.IsDefaultResponse);
- });
- }
-
- [Fact]
- public void CreateProblemResponseTypes_WithIdParameter_Includes404Response()
- {
- // Arrange
- var action = new ActionDescriptor()
- {
- FilterDescriptors = new List()
- {
- new FilterDescriptor(Mock.Of(), FilterScope.Global),
- },
- BoundProperties = new List()
- {
- },
- Parameters = new List()
- {
- new ParameterDescriptor()
- {
- Name = "customerId",
- }
- },
- };
- var description = new ApiDescription()
- {
- ActionDescriptor = action,
- };
-
- var provider = new ApiBehaviorApiDescriptionProvider(new EmptyModelMetadataProvider());
-
- // Act
- var results = provider.CreateProblemResponseTypes(description);
-
- // Assert
- Assert.Collection(
- results.OrderBy(r => r.StatusCode),
- r =>
- {
- Assert.Equal(typeof(ProblemDetails), r.Type);
- Assert.Equal(0, r.StatusCode);
- Assert.True(r.IsDefaultResponse);
- },
- r =>
- {
- Assert.Equal(typeof(ProblemDetails), r.Type);
- Assert.Equal(400, r.StatusCode);
- Assert.False(r.IsDefaultResponse);
- },
- r =>
- {
- Assert.Equal(typeof(ProblemDetails), r.Type);
- Assert.Equal(404, r.StatusCode);
- Assert.False(r.IsDefaultResponse);
- });
- }
- }
-}
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Binders/BodyModelBinderTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Binders/BodyModelBinderTests.cs
index 5cc7342bb3..f1bb2beab9 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Binders/BodyModelBinderTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Binders/BodyModelBinderTests.cs
@@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
var entry = Assert.Single(bindingContext.ModelState);
Assert.Equal(string.Empty, entry.Key);
var errorMessage = Assert.Single(entry.Value.Errors).ErrorMessage;
- Assert.Equal("An error occured while deserializing input data.", errorMessage);
+ Assert.Equal("An error occurred while deserializing input data.", errorMessage);
Assert.Null(entry.Value.Errors[0].Exception);
}
@@ -366,7 +366,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
var entry = Assert.Single(bindingContext.ModelState);
Assert.Equal(string.Empty, entry.Key);
var errorMessage = Assert.Single(entry.Value.Errors).ErrorMessage;
- Assert.Equal("An error occured while deserializing input data.", errorMessage);
+ Assert.Equal("An error occurred while deserializing input data.", errorMessage);
Assert.Null(entry.Value.Errors[0].Exception);
}
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ValidationProblemDetailsTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ValidationProblemDetailsTest.cs
index 1254add386..af4f0d9a34 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ValidationProblemDetailsTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ValidationProblemDetailsTest.cs
@@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Mvc
var problemDescription = new ValidationProblemDetails();
// Assert
- Assert.Equal("One or more validation errors occured.", problemDescription.Title);
+ Assert.Equal("One or more validation errors occurred.", problemDescription.Title);
Assert.Empty(problemDescription.Errors);
}
@@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Mvc
var problemDescription = new ValidationProblemDetails(modelStateDictionary);
// Assert
- Assert.Equal("One or more validation errors occured.", problemDescription.Title);
+ Assert.Equal("One or more validation errors occurred.", problemDescription.Title);
Assert.Collection(
problemDescription.Errors,
item =>
@@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Mvc
var problemDescription = new ValidationProblemDetails(modelStateDictionary);
// Assert
- Assert.Equal("One or more validation errors occured.", problemDescription.Title);
+ Assert.Equal("One or more validation errors occurred.", problemDescription.Title);
Assert.Collection(
problemDescription.Errors,
item =>
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiBehaviorTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiBehaviorTest.cs
index 99703f4cc2..2b83392913 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiBehaviorTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiBehaviorTest.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
@@ -32,14 +33,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
State = "WA",
Zip = "Invalid",
};
- var expected = new ValidationProblemDetails
- {
- Errors =
- {
- ["Zip"] = new[] { @"The field Zip must match the regular expression '\d{5}'." },
- ["Name"] = new[] { "The field Name must be a string with a minimum length of 5 and a maximum length of 30." },
- },
- };
var contactString = JsonConvert.SerializeObject(contactModel);
// Act
@@ -48,12 +41,22 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
Assert.Equal("application/problem+json", response.Content.Headers.ContentType.MediaType);
- var actual = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
- Assert.Equal(expected.Errors.Count, actual.Errors.Count);
- foreach (var error in expected.Errors)
- {
- Assert.Equal(error.Value, actual.Errors[error.Key]);
- }
+ var actual = JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync());
+ Assert.Collection(
+ actual.OrderBy(kvp => kvp.Key),
+ kvp =>
+ {
+ Assert.Equal("Name", kvp.Key);
+ var error = Assert.Single(kvp.Value);
+ Assert.Equal("The field Name must be a string with a minimum length of 5 and a maximum length of 30.", error);
+ },
+ kvp =>
+ {
+ Assert.Equal("Zip", kvp.Key);
+ var error = Assert.Single(kvp.Value);
+ Assert.Equal("The field Zip must match the regular expression '\\d{5}'.", error);
+ }
+ );
}
[Fact]
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiExplorerTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiExplorerTest.cs
index d80f301ca1..7b8ae8d175 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiExplorerTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ApiExplorerTest.cs
@@ -1065,85 +1065,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("ApiExplorerInboundOutbound/SuppressedForLinkGeneration", description.RelativePath);
}
- [Fact]
- public async Task ProblemDetails_AddsProblemAsDefaultErrorResult()
- {
- // Act
- var body = await Client.GetStringAsync("ApiExplorerApiController/ActionWithoutParameters");
- var result = JsonConvert.DeserializeObject>(body);
-
- // Assert
- var description = Assert.Single(result);
- Assert.Collection(
- description.SupportedResponseTypes,
- response =>
- {
- Assert.Equal(0, response.StatusCode);
- Assert.True(response.IsDefaultResponse);
- AssertProblemDetails(response);
- });
- }
-
- [Fact]
- public async Task ProblemDetails_AddsProblemAsErrorResultForBadResult_WhenActionHasParameters()
- {
- // Act
- var body = await Client.GetStringAsync("ApiExplorerApiController/ActionWithSomeParameters");
- var result = JsonConvert.DeserializeObject>(body);
-
- // Assert
- var description = Assert.Single(result);
- Assert.Collection(
- description.SupportedResponseTypes.OrderBy(r => r.StatusCode),
- response =>
- {
- Assert.Equal(0, response.StatusCode);
- Assert.True(response.IsDefaultResponse);
- AssertProblemDetails(response);
- },
- response => Assert.Equal(200, response.StatusCode),
- response =>
- {
- Assert.Equal(400, response.StatusCode);
- Assert.False(response.IsDefaultResponse);
- AssertProblemDetails(response);
- });
- }
-
- [Theory]
- [InlineData("ApiExplorerApiController/ActionWithIdParameter")]
- [InlineData("ApiExplorerApiController/ActionWithIdSuffixParameter")]
- public async Task ProblemDetails_AddsProblemAsErrorResultForNotFoundResult_WhenActionHasAnIdParameters(string url)
- {
- // Act
- var body = await Client.GetStringAsync(url);
- var result = JsonConvert.DeserializeObject>(body);
-
- // Assert
- var description = Assert.Single(result);
- Assert.Collection(
- description.SupportedResponseTypes.OrderBy(r => r.StatusCode),
- response =>
- {
- Assert.Equal(0, response.StatusCode);
- Assert.True(response.IsDefaultResponse);
- AssertProblemDetails(response);
- },
- response => Assert.Equal(200, response.StatusCode),
- response =>
- {
- Assert.Equal(400, response.StatusCode);
- Assert.False(response.IsDefaultResponse);
- AssertProblemDetails(response);
- },
- response =>
- {
- Assert.Equal(404, response.StatusCode);
- Assert.False(response.IsDefaultResponse);
- AssertProblemDetails(response);
- });
- }
-
[Fact]
public async Task ApiBehavior_AddsMultipartFormDataConsumesConstraint_ForActionsWithFormFileParameters()
{
@@ -1157,15 +1078,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("multipart/form-data", requestFormat.MediaType);
}
- private void AssertProblemDetails(ApiExplorerResponseType response)
- {
- Assert.Equal("Microsoft.AspNetCore.Mvc.ProblemDetails", response.ResponseType);
- Assert.Collection(
- GetSortedMediaTypes(response),
- mediaType => Assert.Equal("application/problem+json", mediaType),
- mediaType => Assert.Equal("application/problem+xml", mediaType));
- }
-
private IEnumerable GetSortedMediaTypes(ApiExplorerResponseType apiResponseType)
{
return apiResponseType.ResponseFormats
@@ -1238,4 +1150,4 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
public string FormatterType { get; set; }
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlDataContractSerializerInputFormatterTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlDataContractSerializerInputFormatterTest.cs
index ab36a45d93..97cac2b253 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlDataContractSerializerInputFormatterTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlDataContractSerializerInputFormatterTest.cs
@@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var data = await response.Content.ReadAsStringAsync();
- Assert.Contains("An error occured while deserializing input data.", data);
+ Assert.Contains("An error occurred while deserializing input data.", data);
}
[Fact]
@@ -112,4 +112,4 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
}
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlSerializerInputFormatterTests.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlSerializerInputFormatterTests.cs
index 0589d349d4..e9e6675cff 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlSerializerInputFormatterTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/XmlSerializerInputFormatterTests.cs
@@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var data = await response.Content.ReadAsStringAsync();
- Assert.Contains("An error occured while deserializing input data.", data);
+ Assert.Contains("An error occurred while deserializing input data.", data);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs
index 5fa8242a70..61ce320702 100644
--- a/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs
@@ -447,7 +447,6 @@ namespace Microsoft.AspNetCore.Mvc
new Type[]
{
typeof(DefaultApiDescriptionProvider),
- typeof(ApiBehaviorApiDescriptionProvider),
typeof(JsonPatchOperationsArrayProvider),
}
},
diff --git a/test/WebSites/BasicWebSite/VndErrorDescriptionProvider.cs b/test/WebSites/BasicWebSite/VndErrorDescriptionProvider.cs
index e63cb90bbd..e74df13b5b 100644
--- a/test/WebSites/BasicWebSite/VndErrorDescriptionProvider.cs
+++ b/test/WebSites/BasicWebSite/VndErrorDescriptionProvider.cs
@@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.DependencyInjection;
namespace BasicWebSite
@@ -20,18 +21,18 @@ namespace BasicWebSite
public void OnProvidersExecuting(ErrorDescriptionContext context)
{
if (context.ActionDescriptor.FilterDescriptors.Any(f => f.Filter is VndErrorAttribute) &&
- context.Result is ValidationProblemDetails problemDetails)
+ context.Result is ModelStateDictionary dictionary)
{
var vndErrors = new List();
- foreach (var item in problemDetails.Errors)
+ foreach (var item in dictionary)
{
- foreach (var message in item.Value)
+ foreach (var modelError in item.Value.Errors)
{
vndErrors.Add(new VndError
{
- LogRef = problemDetails.Title,
+ LogRef = modelError.ErrorMessage,
Path = item.Key,
- Message = message,
+ Message = modelError.ErrorMessage,
});
}
}
@@ -40,4 +41,4 @@ namespace BasicWebSite
}
}
}
-}
\ No newline at end of file
+}