/// <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);
        }
        /// <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 #4
0
        /// <inheritdoc />
        public virtual bool CanRead(BodyParserContext context)
        {
            if (this.SupportedMediaTypes.Count == 0)
            {
                throw new InvalidOperationException($"{this.GetType().FullName} does not specify any support media types. Ensure that {nameof(this.SupportedMediaTypes)} has been populated with at least one value");
            }

            if (!this.CanReadType(context.BodyType))
            {
                return(false);
            }

            var contentType = context.HttpContext.Request.ContentType;

            if (string.IsNullOrEmpty(contentType))
            {
                return(false);
            }

            // Confirm the request's content type is more specific than a media type this formatter supports e.g. OK if
            // client sent "text/plain" data and this formatter supports "text/*".
            return(this.IsSubsetOfAnySupportedContentType(contentType));
        }
Beispiel #5
0
 /// <inheritdoc/>
 public abstract Task <object> ReadAsync(BodyParserContext context);