/// <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(); } } }
public void Create_WhenCalled_ShouldReturnApiException() { // Arrange var sut = new ApiExceptionFactory(); // Act var actual = sut.Create(HttpStatusCode.InternalServerError, string.Empty); // Assert actual.Should().BeOfType <ApiException>(); }
public void Create_WhenCalledWithForbidden_ShouldReturnForbiddenException() { // Arrange var sut = new ApiExceptionFactory(); // Act var actual = sut.Create(HttpStatusCode.Forbidden, string.Empty); // Assert actual.Should().BeOfType <ForbiddenException>(); }
public void Create_WhenCalledWithUnauthorized_ShouldReturnUnauthorizedException() { // Arrange var sut = new ApiExceptionFactory(); // Act var actual = sut.Create(HttpStatusCode.Unauthorized, string.Empty); // Assert actual.Should().BeOfType <UnauthorizedException>(); }
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); }