コード例 #1
0
        public void HandleComponentModelValidationException(ComponentModelValidationException exception, ExceptionContext context)
        {
            foreach (var key in exception.ValidationResult.MemberNames)
            {
                context.ModelState.TryAddModelException(key, exception);
            }

            var details = new ValidationProblemDetails(context.ModelState);

            context.Result           = new BadRequestObjectResult(details);
            context.ExceptionHandled = true;
        }
コード例 #2
0
        public void GivenValidationExceptions_WhenMapped_ThenReturnsBadRequestHttpStatusWithProperMessage()
        {
            //Given
            const string message = "Message";
            var          fluentValidationException = new ValidationException(message);
            var          dataAnnotationsException  = new System.ComponentModel.DataAnnotations.ValidationException(message);

            var exceptions = new Exception[] { fluentValidationException, dataAnnotationsException };

            foreach (var validationException in exceptions)
            {
                //When
                var codeInfo = ExceptionToHttpStatusMapper.Map(fluentValidationException);

                //Then
                codeInfo.Code.Should().Be(HttpStatusCode.BadRequest);
                codeInfo.Message.Should().Be(message);
            }
        }
コード例 #3
0
        public async Task AsHttpResponseData_ContentTypeIsJson_ReturnsResponseSerializedAsJson()
        {
            // arrange
            const string expectedXml = "{\"error\":{\"code\":\"VALIDATION_EXCEPTION\",\"message\":\"BundleIdAlreadyInUse\"}}";
            var          request     = new MockedHttpRequestData(new MockedFunctionContext());

            request.HttpRequestDataMock.Setup(x => x.Headers).Returns(new Microsoft.Azure.Functions.Worker.Http.HttpHeadersCollection(
                                                                          new[] { new KeyValuePair <string, IEnumerable <string> >(HeaderNames.ContentType, new[] { MediaTypeNames.Application.Json }) }));
            const string validationErrorMessage = nameof(BundleCreatedResponse.BundleIdAlreadyInUse);
            var          exception = new System.ComponentModel.DataAnnotations.ValidationException(validationErrorMessage);

            // act
            var actual = await exception.AsHttpResponseDataAsync(request.HttpRequestData).ConfigureAwait(false);

            var content = Encoding.UTF8.GetString(((MemoryStream)actual.Body).ToArray());

            // assert
            Assert.Equal(expectedXml, content);
        }
コード例 #4
0
 public static ExceptionModel ToHttpException(this Exception e)
 {
     return(e switch
     {
         FluentValidation.ValidationException exception => new ValidationExceptionModel
         {
             Message = e.Message,
             InnerException = e?.InnerException?.ToHttpException(),
             StackTrace = e.StackTrace,
             ValidationErrors = exception.Errors.Select(x => new ValidationErrorModel
             {
                 Message = x.ErrorMessage,
                 PropertyName = x.PropertyName,
                 AttemptedValue = x.AttemptedValue,
                 ErrorCode = x.ErrorCode
             })
                                .ToList()
         },
         System.ComponentModel.DataAnnotations.ValidationException exception => new
         ValidationExceptionModel()
         {
             Message = e.Message,
             InnerException = e?.InnerException?.ToHttpException(),
             StackTrace = e.StackTrace,
             ValidationErrors = exception?.ValidationResult?.MemberNames?.Select(x =>
                                                                                 new ValidationErrorModel
             {
                 Message = (e as System.ComponentModel.DataAnnotations.ValidationException)
                           ?.ValidationResult?.ErrorMessage ?? String.Empty,
                 PropertyName = x
             })
                                ?.ToList()
         },
         _ => new ExceptionModel
         {
             Message = e.Message,
             InnerException = e?.InnerException?.ToHttpException(),
             StackTrace = e.StackTrace
         }
     });
コード例 #5
0
        public static HttpStatusCodeInfo Map(Exception exception)
        {
            if (CustomMaps.ContainsKey(exception.GetType()))
            {
                return(CustomMaps[exception.GetType()](exception));
            }

            var code = exception switch
            {
                ValidationException _ => HttpStatusCode.BadRequest,
                System.ComponentModel.DataAnnotations.ValidationException _ => HttpStatusCode.BadRequest,
                ArgumentException _ => HttpStatusCode.BadRequest,
                UnauthorizedAccessException _ => HttpStatusCode.Unauthorized,
                InvalidOperationException _ => HttpStatusCode.Forbidden,
                NotFoundException _ => HttpStatusCode.NotFound,
                OptimisticConcurrencyException _ => HttpStatusCode.Conflict,
                NotImplementedException _ => HttpStatusCode.NotImplemented,
                _ => HttpStatusCode.InternalServerError
            };

            return(new HttpStatusCodeInfo(code, exception.Message));
        }
コード例 #6
0
        public async Task AsHttpResponseData_ExceptionIsDataAnnotationException_ReturnsResponseWithGenericErrorAndStatusValidationError()
        {
            // arrange
            var          request = new MockedHttpRequestData(new MockedFunctionContext());
            const string validationErrorMessage = nameof(BundleCreatedResponse.BundleIdAlreadyInUse);
            var          exception = new System.ComponentModel.DataAnnotations.ValidationException(validationErrorMessage);

            // act
            var actual = await exception.AsHttpResponseDataAsync(request.HttpRequestData).ConfigureAwait(false);

            var actualFunctionError = JsonSerializer.Deserialize <ErrorResponse>(
                ((MemoryStream)actual.Body).ToArray(),
                new JsonSerializerOptions {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            }) !;
            var error = actualFunctionError.Error;

            // assert
            Assert.Equal(HttpStatusCode.BadRequest, actual.StatusCode);
            Assert.Equal("VALIDATION_EXCEPTION", error.Code);
            Assert.Equal(nameof(BundleCreatedResponse.BundleIdAlreadyInUse), error.Message);
            Assert.Null(error.Target);
            Assert.Null(error.Details);
        }
コード例 #7
0
        /// <summary>
        /// Given a <see cref="System.ComponentModel.DataAnnotations.ValidationException"/> will convert it to an
        /// equivalent <see cref="ValidationFailedOperationResult" /> to be output to the user.
        /// </summary>
        /// <param name="validationException">The exception to be converted.</param>
        /// <returns>The response to send back to the client.</returns>
        // ReSharper disable once MemberCanBePrivate.Global This is used in generated code
        public static ValidationFailedOperationResult ToValidationFailedOperationResult(System.ComponentModel.DataAnnotations.ValidationException validationException)
        {
            var validationResult = validationException.ValidationResult;

            if (!validationResult.MemberNames.Any())
            {
                return(new ValidationFailedOperationResult(validationResult.ErrorMessage));
            }

            var errorMessages = (IEnumerable <string>) new[] { validationResult.ErrorMessage };

            return(new ValidationFailedOperationResult(validationResult.MemberNames.ToDictionary(m => m, m => errorMessages)));
        }