/// <inheritdoc />
        protected sealed override async Task <object> ReadRequestBodyAsync(
            BodyParserContext context,
            Encoding encoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            var httpContext = context.HttpContext;

            var(inputStream, usesTranscodingStream) = this.GetInputStream(httpContext, encoding);

            try
            {
                // This is copied from JsonConvert.PopulateObject to avoid creating a new JsonSerializer on each
                // execution.
                using var stringReader = new StreamReader(inputStream);
                using var jsonReader   = new JsonTextReader(stringReader)
                      {
                          CloseInput = false
                      };

                try
                {
                    this._bodyJsonSerializer.Populate(jsonReader, context.Instance);
                }
                catch (JsonException e)
                {
                    throw _invalidJson.Create(e.Message);
                }

                if (await jsonReader.ReadAsync() && jsonReader.TokenType != JsonToken.Comment)
                {
                    throw _invalidJson.Create("Additional text found in JSON");
                }
            }
            finally
            {
                if (usesTranscodingStream)
                {
                    // TODO: When we target .net 5.0 can make use of built-in transcoding Stream with async Dispose
                    // await inputStream.DisposeAsync();
                }
            }

            // We have populated the object given to us, return as-is.
            return(context.Instance);
        }
        /// <inheritdoc />
        protected sealed override async Task <object> ReadRequestBodyAsync(
            BodyParserContext context,
            Encoding encoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            var httpContext = context.HttpContext;

            var(inputStream, usesTranscodingStream) = this.GetInputStream(httpContext, encoding);

            try
            {
                return(await JsonSerializer.DeserializeAsync(inputStream, context.BodyType, this._serializerOptions));
            }
            catch (JsonException jsonException)
            {
                throw _invalidJson.Create(jsonException.Message);
            }
            catch (Exception exception) when(exception is FormatException || exception is OverflowException)
            {
                // The code in System.Text.Json never throws these exceptions. However a custom converter could produce these errors for instance when
                // parsing a value. These error messages are considered safe to report to users

                throw _invalidJson.Create(exception.Message);
            }
            finally
            {
                if (usesTranscodingStream)
                {
                    // TODO: When we target .net 5.0 can make use of built-in transcoding Stream with async Dispose
                    // await inputStream.DisposeAsync();
                }
            }
        }
Beispiel #3
0
        public void Create_WhenCalled_ShouldReturnApiException()
        {
            // Arrange
            var sut = new ApiExceptionFactory();

            // Act
            var actual = sut.Create(HttpStatusCode.InternalServerError, string.Empty);

            // Assert
            actual.Should().BeOfType <ApiException>();
        }
Beispiel #4
0
        public void Create_WhenCalledWithForbidden_ShouldReturnForbiddenException()
        {
            // Arrange
            var sut = new ApiExceptionFactory();

            // Act
            var actual = sut.Create(HttpStatusCode.Forbidden, string.Empty);

            // Assert
            actual.Should().BeOfType <ForbiddenException>();
        }
Beispiel #5
0
        public void Create_WhenCalledWithUnauthorized_ShouldReturnUnauthorizedException()
        {
            // Arrange
            var sut = new ApiExceptionFactory();

            // Act
            var actual = sut.Create(HttpStatusCode.Unauthorized, string.Empty);

            // Assert
            actual.Should().BeOfType <UnauthorizedException>();
        }
Beispiel #6
0
        public void Create_WhenCalledWithBadRequest_ShouldReturnBadRequestException()
        {
            // Arrange
            var sut = new ApiExceptionFactory();

            // Act
            var actual = sut.Create(HttpStatusCode.BadRequest, string.Empty);

            // Assert
            actual.Should().BeOfType <BadRequestException>();
        }
        /// <inheritdoc/>
        public override async Task <object> ReadAsync(BodyParserContext context)
        {
            var operation  = context.Instance;
            var properties = context.OperationContext.Descriptor.Properties;

            var form = await context.HttpContext.Request.ReadFormAsync();

            foreach (var item in form)
            {
                WriteStringValues(operation, properties, item.Key, item.Value, exception => throw _invalidForm.Create(exception.Message));
            }

            if (form.Files.Any())
            {
                var props = properties.Where(x => x.PropertyType.IsAssignableFrom(typeof(IFormFile))).ToList();
                foreach (var file in form.Files)
                {
                    var propertyToWrite = props.SingleOrDefault(x => string.Equals(x.Name, file.Name, StringComparison.OrdinalIgnoreCase));
                    if (propertyToWrite == null)
                    {
                        continue;
                    }

                    propertyToWrite.SetValue(operation, file);
                }
            }

            // We have populated the object given to us, return as-is.
            return(operation);
        }