示例#1
0
        public async override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }
            var request = context.HttpContext.Request.HttpContext.Request;

            try
            {
                var           ret     = new PayPalIPNRequest();
                StringBuilder rawBody = new StringBuilder();
                foreach (string key in request.Form.Keys)
                {
                    string strVal = request.Form[key].ToString();
                    rawBody.Append(key + "=" + strVal + "&");
                    strVal = WebUtility.UrlDecode(strVal);
                    if (key.StartsWith("item_name"))
                    {
                        PurchasedItem itm = addGetItemFromList(key, "item_name", ret);
                        itm.item_name = strVal;
                    }
                    else if (key.StartsWith("item_number"))
                    {
                        PurchasedItem itm = addGetItemFromList(key, "item_number", ret);
                        itm.item_number = strVal;
                    }
                    else if (key.StartsWith("quantity"))
                    {
                        PurchasedItem itm = addGetItemFromList(key, "quantity", ret);
                        int           val;
                        if (int.TryParse(strVal, out val))
                        {
                            itm.quantity = val;
                        }
                    }
                    else if (key.StartsWith("mc_gross"))
                    {
                        PurchasedItem itm = addGetItemFromList(key, "mc_gross", ret);
                        double        val;
                        if (double.TryParse(strVal, out val))
                        {
                            itm.mc_gross = val;
                        }
                    }
                    else if (key.StartsWith("mc_shipping"))
                    {
                        PurchasedItem itm = addGetItemFromList(key, "mc_shipping", ret);
                        double        val;
                        if (double.TryParse(strVal, out val))
                        {
                            itm.mc_gross = val;
                        }
                    }
                    else if (key.StartsWith("option_name"))
                    {
                        PurchasedItem itm = addGetItemFromList(key, "option_name", ret);
                        itm.item_number = strVal;
                    }
                    else if (key.StartsWith("option_selection"))
                    {
                        PurchasedItem itm = addGetItemFromList(key, "option_selection", ret);
                        itm.item_number = strVal;
                    }
                    else if (key.StartsWith("fraud_management_pending_filters_"))
                    {
                        int val;
                        if (int.TryParse(strVal, out val))
                        {
                            ret.fraud_management_pending_filters.Add(val);
                        }
                    }
                    else
                    {
                        PropertyInfo propInfo = typeof(PayPalIPNRequest).GetProperty(key);
                        if (propInfo != null)
                        {
                            if (propInfo.PropertyType == typeof(DateTime))
                            {
                                DateTime val;
                                string[] formats = new string[] { "HH:mm:ss dd MMM yyyy PDT", "HH:mm:ss dd MMM yyyy PST",
                                                                  "HH:mm:ss dd MMM, yyyy PST", "HH:mm:ss dd MMM, yyyy PDT",
                                                                  "HH:mm:ss MMM dd, yyyy PST", "HH:mm:ss MMM dd, yyyy PDT" };
                                if (DateTime.TryParseExact(strVal, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out val))
                                {
                                    val = TimeZoneInfo.ConvertTimeToUtc(val, TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));
                                    propInfo.SetValue(ret, val, null);
                                }
                            }
                            else if (propInfo.PropertyType == typeof(int))
                            {
                                int val;
                                if (int.TryParse(strVal, out val))
                                {
                                    propInfo.SetValue(ret, val, null);
                                }
                            }
                            else if (propInfo.PropertyType == typeof(double))
                            {
                                double val;
                                if (double.TryParse(strVal, out val))
                                {
                                    propInfo.SetValue(ret, val, null);
                                }
                            }
                            else
                            {
                                propInfo.SetValue(ret, strVal, null);
                            }
                        }
                    }
                }
                ret.rawBody = rawBody.ToString().TrimEnd("&".ToCharArray());
                return(await InputFormatterResult.SuccessAsync(ret));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return(await InputFormatterResult.FailureAsync());
            }
        }
示例#2
0
        public Task <InputFormatterResult> ReadAsync(InputFormatterContext context)
        {
            var assembly = Assembly.Load("BadAssemblyThatCantLoad");

            return(Task.FromResult(InputFormatterResult.Success(model: null)));
        }
示例#3
0
    /// <inheritdoc />
    public override async Task <InputFormatterResult> ReadRequestBodyAsync(
        InputFormatterContext context,
        Encoding encoding)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

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

        var    request           = context.HttpContext.Request;
        Stream readStream        = new NonDisposableStream(request.Body);
        var    disposeReadStream = false;

        if (readStream.CanSeek)
        {
            // The most common way of getting here is the user has request buffering on.
            // However, request buffering isn't eager, and consequently it will peform pass-thru synchronous
            // reads as part of the deserialization.
            // To avoid this, drain and reset the stream.
            var position = request.Body.Position;
            await readStream.DrainAsync(CancellationToken.None);

            readStream.Position = position;
        }
        else if (!_options.SuppressInputFormatterBuffering)
        {
            // XmlSerializer does synchronous reads. In order to avoid blocking on the stream, we asynchronously
            // read everything into a buffer, and then seek back to the beginning.
            var memoryThreshold = DefaultMemoryThreshold;
            var contentLength   = request.ContentLength.GetValueOrDefault();
            if (contentLength > 0 && contentLength < memoryThreshold)
            {
                // If the Content-Length is known and is smaller than the default buffer size, use it.
                memoryThreshold = (int)contentLength;
            }

            readStream = new FileBufferingReadStream(request.Body, memoryThreshold);
            // Ensure the file buffer stream is always disposed at the end of a request.
            request.HttpContext.Response.RegisterForDispose(readStream);

            await readStream.DrainAsync(CancellationToken.None);

            readStream.Seek(0L, SeekOrigin.Begin);
            disposeReadStream = true;
        }

        try
        {
            var type = GetSerializableType(context.ModelType);
            using var xmlReader = CreateXmlReader(readStream, encoding, type);

            var serializer = GetCachedSerializer(type);

            var deserializedObject = serializer.Deserialize(xmlReader);

            // Unwrap only if the original type was wrapped.
            if (type != context.ModelType)
            {
                if (deserializedObject is IUnwrappable unwrappable)
                {
                    deserializedObject = unwrappable.Unwrap(declaredType: context.ModelType);
                }
            }

            return(InputFormatterResult.Success(deserializedObject));
        }
        // XmlSerializer wraps actual exceptions (like FormatException or XmlException) into an InvalidOperationException
        // https://github.com/dotnet/corefx/blob/master/src/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs#L652
        catch (InvalidOperationException exception) when(exception.InnerException != null &&
                                                         exception.InnerException.InnerException == null &&
                                                         string.Equals("Microsoft.GeneratedCode", exception.InnerException.Source, StringComparison.InvariantCulture))
        {
            // Know this was an XML parsing error because the inner Exception was thrown in the (generated)
            // assembly the XmlSerializer uses for parsing. The problem did not arise lower in the stack i.e. it's
            // not (for example) an out-of-memory condition.
            throw new InputFormatterException(Resources.ErrorDeserializingInputData, exception.InnerException);
        }
        catch (InvalidOperationException exception) when(exception.InnerException is FormatException ||
                                                         exception.InnerException is XmlException)
        {
            throw new InputFormatterException(Resources.ErrorDeserializingInputData, exception.InnerException);
        }
        finally
        {
            if (disposeReadStream)
            {
                await readStream.DisposeAsync();
            }
        }
    }
 public async override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
 {
     return(await InputFormatterResult.SuccessAsync(new { fred = true }));
 }
        /// <inheritdoc />
        public override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.HttpContext.Request;

            using (var bsonReader = CreateBsonReader(context, request.Body))
            {
                bsonReader.CloseInput = false;

                var successful = true;
                EventHandler <Newtonsoft.Json.Serialization.ErrorEventArgs> errorHandler = (sender, eventArgs) =>
                {
                    successful = false;

                    var exception = eventArgs.ErrorContext.Error;

                    // Handle path combinations such as "" + "Property", "Parent" + "Property", or "Parent" + "[12]".
                    var key = eventArgs.ErrorContext.Path;
                    if (!string.IsNullOrEmpty(context.ModelName))
                    {
                        if (string.IsNullOrEmpty(eventArgs.ErrorContext.Path))
                        {
                            key = context.ModelName;
                        }
                        else if (eventArgs.ErrorContext.Path[0] == '[')
                        {
                            key = context.ModelName + eventArgs.ErrorContext.Path;
                        }
                        else
                        {
                            key = context.ModelName + "." + eventArgs.ErrorContext.Path;
                        }
                    }

                    var metadata = GetPathMetadata(context.Metadata, eventArgs.ErrorContext.Path);
                    context.ModelState.TryAddModelError(key, eventArgs.ErrorContext.Error, metadata);

                    // Error must always be marked as handled
                    // Failure to do so can cause the exception to be rethrown at every recursive level and
                    // overflow the stack for x64 CLR processes
                    eventArgs.ErrorContext.Handled = true;
                };

                var type           = context.ModelType;
                var jsonSerializer = CreateJsonSerializer();
                jsonSerializer.Error += errorHandler;

                object model;
                try
                {
                    model = jsonSerializer.Deserialize(bsonReader, type);
                }
                finally
                {
                    // Clean up the error handler in case CreateJsonSerializer() reuses a serializer
                    jsonSerializer.Error -= errorHandler;
                }

                if (successful)
                {
                    return(InputFormatterResult.SuccessAsync(model));
                }

                return(InputFormatterResult.FailureAsync());
            }
        }
示例#6
0
 public Task <InputFormatterResult> ReadAsync(InputFormatterContext context)
 {
     return(InputFormatterResult.NoValueAsync());
 }
示例#7
0
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            try
            {
                var request = context.HttpContext.Request;

                if (request.Body.CanSeek)
                {
                    request.Body.Seek(0, SeekOrigin.Begin);
                }

                object model = context.ModelType.GetConstructor(Type.EmptyTypes).Invoke(null);

                string          boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType), DefaultFormOptions.MultipartBoundaryLengthLimit);
                MultipartReader reader   = new MultipartReader(boundary, request.Body);

                bool isSuccess  = false;
                bool isReadable = true;

                do
                {
                    MultipartSection section = await reader.ReadNextSectionAsync();

                    isReadable = section != null;
                    if (isReadable && ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition))
                    {
                        if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            SetProperty(model, FileNamePropertyName, HeaderUtilities.RemoveQuotes(contentDisposition.FileName).ToString());
                            SetProperty(model, StreamPropertyName, section.Body, false);

                            isSuccess = true;

                            isReadable = false;
                        }
                        else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                        {
                            string   key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).ToString();
                            Encoding encoding = GetEncoding(section);

                            string value = null;

                            using (StreamReader streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                value = await streamReader.ReadToEndAsync();

                                if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = string.Empty;
                                }
                            }

                            SetProperty(model, key, value);

                            isSuccess = true;
                        }
                    }
                }while (isReadable);

                if (!isSuccess && !context.TreatEmptyInputAsDefaultValue)
                {
                    return(InputFormatterResult.NoValue());
                }

                return(InputFormatterResult.Success(model));
            }
            catch
            {
                return(InputFormatterResult.Failure());
            }
        }
        public override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            encoding = encoding ?? SelectCharacterEncoding(context);
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }
            var request = context.HttpContext.Request;

            try
            {
                object inputModel     = null;
                var    formCollection = request.Form.ToDictionary(f => f.Key, f => f.Value.ToString());
                if (formCollection.Count > 0 && FormUrlEncodedJson.TryParse(formCollection, out var jObject))
                {
                    inputModel = jObject.ToObject(context.ModelType);
                }
                return(Task.FromResult(inputModel != null ? InputFormatterResult.Success(inputModel) : InputFormatterResult.Failure()));
            }
            catch (Exception)
            {
                return(Task.FromResult(InputFormatterResult.Failure()));
            }
        }
示例#9
0
    /// <inheritdoc />
    public override async Task <InputFormatterResult> ReadRequestBodyAsync(
        InputFormatterContext context,
        Encoding encoding)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

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

        var httpContext = context.HttpContext;
        var request     = httpContext.Request;

        var suppressInputFormatterBuffering = _options.SuppressInputFormatterBuffering;

        var readStream        = request.Body;
        var disposeReadStream = false;

        if (readStream.CanSeek)
        {
            // The most common way of getting here is the user has request buffering on.
            // However, request buffering isn't eager, and consequently it will peform pass-thru synchronous
            // reads as part of the deserialization.
            // To avoid this, drain and reset the stream.
            var position = request.Body.Position;
            await readStream.DrainAsync(CancellationToken.None);

            readStream.Position = position;
        }
        else if (!suppressInputFormatterBuffering)
        {
            // JSON.Net does synchronous reads. In order to avoid blocking on the stream, we asynchronously
            // read everything into a buffer, and then seek back to the beginning.
            var memoryThreshold = _jsonOptions.InputFormatterMemoryBufferThreshold;
            var contentLength   = request.ContentLength.GetValueOrDefault();
            if (contentLength > 0 && contentLength < memoryThreshold)
            {
                // If the Content-Length is known and is smaller than the default buffer size, use it.
                memoryThreshold = (int)contentLength;
            }

            readStream = new FileBufferingReadStream(request.Body, memoryThreshold);
            // Ensure the file buffer stream is always disposed at the end of a request.
            httpContext.Response.RegisterForDispose(readStream);

            await readStream.DrainAsync(CancellationToken.None);

            readStream.Seek(0L, SeekOrigin.Begin);

            disposeReadStream = true;
        }

        var       successful = true;
        Exception?exception  = null;
        object?   model;

        using (var streamReader = context.ReaderFactory(readStream, encoding))
        {
            using var jsonReader  = new JsonTextReader(streamReader);
            jsonReader.ArrayPool  = _charPool;
            jsonReader.CloseInput = false;

            var type           = context.ModelType;
            var jsonSerializer = CreateJsonSerializer(context);
            jsonSerializer.Error += ErrorHandler;

            if (_jsonOptions.ReadJsonWithRequestCulture)
            {
                jsonSerializer.Culture = CultureInfo.CurrentCulture;
            }

            try
            {
                model = jsonSerializer.Deserialize(jsonReader, type);
            }
            finally
            {
                // Clean up the error handler since CreateJsonSerializer() pools instances.
                jsonSerializer.Error -= ErrorHandler;
                ReleaseJsonSerializer(jsonSerializer);

                if (disposeReadStream)
                {
                    await readStream.DisposeAsync();
                }
            }
        }

        if (successful)
        {
            if (model == null && !context.TreatEmptyInputAsDefaultValue)
            {
                // Some nonempty inputs might deserialize as null, for example whitespace,
                // or the JSON-encoded value "null". The upstream BodyModelBinder needs to
                // be notified that we don't regard this as a real input so it can register
                // a model binding error.
                return(InputFormatterResult.NoValue());
            }
            else
            {
                return(InputFormatterResult.Success(model));
            }
        }

        if (exception is not null && exception is not(JsonException or OverflowException or FormatException))
        {
            // At this point we've already recorded all exceptions as an entry in the ModelStateDictionary.
            // We only need to rethrow an exception if we believe it needs to be handled by something further up
            // the stack.
            // JsonException, OverflowException, and FormatException are assumed to be only encountered when
            // parsing the JSON and are consequently "safe" to be exposed as part of ModelState. Everything else
            // needs to be rethrown.

            var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception);
            exceptionDispatchInfo.Throw();
        }

        return(InputFormatterResult.Failure());

        void ErrorHandler(object?sender, Newtonsoft.Json.Serialization.ErrorEventArgs eventArgs)
        {
            // Skipping error, if it's already marked as handled
            // This allows user code to implement its own error handling
            if (eventArgs.ErrorContext.Handled)
            {
                return;
            }

            successful = false;

            // The following addMember logic is intended to append the names of missing required properties to the
            // ModelStateDictionary key. Normally, just the ModelName and ErrorContext.Path is used for this key,
            // but ErrorContext.Path does not include the missing required property name like we want it to.
            // For example, given the following class and input missing the required "Name" property:
            //
            // class Person
            // {
            //     [JsonProperty(Required = Required.Always)]
            //     public string Name { get; set; }
            // }
            //
            // We will see the following ErrorContext:
            //
            // Error   {"Required property 'Name' not found in JSON. Path 'Person'..."} System.Exception {Newtonsoft.Json.JsonSerializationException}
            // Member  "Name"   object {string}
            // Path    "Person" string
            //
            // So we update the path used for the ModelStateDictionary key to be "Person.Name" instead of just "Person".
            // See https://github.com/aspnet/Mvc/issues/8509
            var path   = eventArgs.ErrorContext.Path;
            var member = eventArgs.ErrorContext.Member as string;

            // There are some deserialization exceptions that include the member in the path but not at the end.
            // For example, given the following classes and invalid input like { "b": { "c": { "d": abc } } }:
            //
            // class A
            // {
            //     public B B { get; set; }
            // }
            // class B
            // {
            //     public C C { get; set; }
            // }
            // class C
            // {
            //     public string D { get; set; }
            // }
            //
            // We will see the following ErrorContext:
            //
            // Error   {"Unexpected character encountered while parsing value: b. Path 'b.c.d'..."} System.Exception {Newtonsoft.Json.JsonReaderException}
            // Member  "c"     object {string}
            // Path    "b.c.d" string
            //
            // Notice that Member "c" is in the middle of the Path "b.c.d". The error handler gets invoked for each level of nesting.
            // null, "b", "c" and "d" are each a Member in different ErrorContexts all reporting the same parsing error.
            //
            // The parsing error is reported as a JsonReaderException instead of as a JsonSerializationException like
            // for missing required properties. We use the exception type to filter out these errors and keep the path used
            // for the ModelStateDictionary key as "b.c.d" instead of "b.c.d.c"
            // See https://github.com/dotnet/aspnetcore/issues/33451
            var addMember = !string.IsNullOrEmpty(member) && eventArgs.ErrorContext.Error is JsonSerializationException;

            // There are still JsonSerilizationExceptions that set ErrorContext.Member but include it at the
            // end of ErrorContext.Path already. The following logic attempts to filter these out.
            if (addMember)
            {
                // Path.Member case (path.Length < member.Length) needs no further checks.
                if (path.Length == member !.Length)
                {
                    // Add Member in Path.Member case but not for Path.Path.
                    addMember = !string.Equals(path, member, StringComparison.Ordinal);
                }
                else if (path.Length > member.Length)
                {
                    // Finally, check whether Path already ends or starts with Member.
                    if (member[0] == '[')
                    {
                        addMember = !path.EndsWith(member, StringComparison.Ordinal);
                    }
                    else
                    {
                        addMember = !path.EndsWith($".{member}", StringComparison.Ordinal) &&
                                    !path.EndsWith($"['{member}']", StringComparison.Ordinal) &&
                                    !path.EndsWith($"[{member}]", StringComparison.Ordinal);
                    }
                }
            }

            if (addMember)
            {
                path = ModelNames.CreatePropertyModelName(path, member);
            }

            // Handle path combinations such as ""+"Property", "Parent"+"Property", or "Parent"+"[12]".
            var key = ModelNames.CreatePropertyModelName(context.ModelName, path);

            exception = eventArgs.ErrorContext.Error;

            var metadata            = GetPathMetadata(context.Metadata, path);
            var modelStateException = WrapExceptionForModelState(exception);

            context.ModelState.TryAddModelError(key, modelStateException, metadata);

            _logger.JsonInputException(exception);

            // Error must always be marked as handled
            // Failure to do so can cause the exception to be rethrown at every recursive level and
            // overflow the stack for x64 CLR processes
            eventArgs.ErrorContext.Handled = true;
        }
        /// <inheritdoc />
        public sealed override async Task <InputFormatterResult> ReadRequestBodyAsync(
            InputFormatterContext 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 = httpContext.Request.Body;

            ApplicationPayload?model;

            try
            {
                using var inputStreamReader = new StreamReader(inputStream);

                var inputJsonString = await inputStreamReader.ReadToEndAsync();

                // Determine options name to use (in case multiple are registered)
                var options = httpContext.Request.RouteValues.TryGetValue(RouteKeyConstants.OptionsName, out object optionsName)
                        ? _options.Get(optionsName.ToString())
                        : _options.CurrentValue;

                // Get secret
                var secret = Encoding.ASCII.GetBytes(options.EndpointSigningKey);

                var signatureBytes = Encoding.UTF8.GetBytes(context.HttpContext.Request.Headers[HeaderSpaceTimestamp] + ":" + inputJsonString);
                using (var hmSha1 = new HMACSHA256(secret))
                {
                    var signatureHash   = hmSha1.ComputeHash(signatureBytes);
                    var signatureString = ToHexString(signatureHash);
                    if (options.ValidatePayloadSignature && !signatureString.Equals(context.HttpContext.Request.Headers[HeaderSpaceSignature]))
                    {
                        throw new InvalidOperationException("The webhook signature does not match the webhook payload. Make sure the endpoint signing key is configured correctly in your Space organization, and the current application.");
                    }
                }

                model = JsonSerializer.Deserialize(inputJsonString, context.ModelType, _jsonSerializerOptions) as ApplicationPayload;
                if (model != null)
                {
                    PropagatePropertyAccessPathHelper.SetAccessPathForValue(string.Empty, false, model);
                }

                var payloadVerificationTokenValue = GetPayloadVerificationTokenValue(model);
                if (!string.IsNullOrEmpty(payloadVerificationTokenValue))
                {
                    if (options.ValidatePayloadVerificationToken && payloadVerificationTokenValue != options.EndpointVerificationToken)
                    {
                        throw new InvalidOperationException("The webhook verification token does not your configured verification token. Make sure the endpoint verification token is configured correctly in your Space organization, and the current application.");
                    }
                }
            }
            catch (JsonException jsonException)
            {
                var path = jsonException.Path;

                var formatterException = new InputFormatterException(jsonException.Message, jsonException);
                context.ModelState.TryAddModelError(path, formatterException, context.Metadata);

                Log.JsonInputException(_logger, jsonException);

                return(await InputFormatterResult.FailureAsync());
            }
            catch (Exception exception) when(exception is FormatException || exception is OverflowException)
            {
                context.ModelState.TryAddModelError(string.Empty, exception, context.Metadata);

                Log.JsonInputException(_logger, exception);

                return(await InputFormatterResult.FailureAsync());
            }

            if (model == null && !context.TreatEmptyInputAsDefaultValue)
            {
                return(await InputFormatterResult.NoValueAsync());
            }

            Log.JsonInputSuccess(_logger, context.ModelType);

            return(await InputFormatterResult.SuccessAsync(model));
        }
示例#11
0
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            var reader = context.ReaderFactory.Invoke(context.HttpContext.Request.Body, encoding);

            return(await InputFormatterResult.SuccessAsync(await reader.ReadToEndAsync()));
        }
示例#12
0
        public Task <InputFormatterResult> ReadAsync(InputFormatterContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.HttpContext.Request;

            if (request.ContentLength == 0)
            {
                return(InputFormatterResult.SuccessAsync(null));
            }

            try
            {
                var body = GetRequestBody(context.HttpContext.Request.Body);

                object model = null;

                if (_jsonApiContext.IsRelationshipPath)
                {
                    model = _deSerializer.DeserializeRelationship(body);
                }
                else
                {
                    model = _deSerializer.Deserialize(body);
                }


                if (model == null)
                {
                    _logger?.LogError("An error occurred while de-serializing the payload");
                }

                if (context.HttpContext.Request.Method == "PATCH")
                {
                    bool idMissing;
                    if (model is IList list)
                    {
                        idMissing = CheckForId(list);
                    }
                    else
                    {
                        idMissing = CheckForId(model);
                    }
                    if (idMissing)
                    {
                        _logger?.LogError("Payload must include id attribute");
                        throw new JsonApiException(400, "Payload must include id attribute");
                    }
                }
                return(InputFormatterResult.SuccessAsync(model));
            }
            catch (Exception ex)
            {
                _logger?.LogError(new EventId(), ex, "An error occurred while de-serializing the payload");
                context.ModelState.AddModelError(context.ModelName, ex, context.Metadata);
                return(InputFormatterResult.FailureAsync());
            }
        }
        public async override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            string body = await ReadBodyAsync(context, encoding);

            return(InputFormatterResult.Success(body));
        }
示例#14
0
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

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

            if (encoding.EncodingName != Encoding.UTF8.EncodingName)
            {
                throw new FhirFatalException(System.Net.HttpStatusCode.BadRequest, "FHIR supports UTF-8 encoding exclusively, not " + encoding.WebName);
            }


            var request = context.HttpContext.Request;

            // TODO: Brian: Would like to know what the issue is here? Will this be resolved by the Async update to the core?
            if (!request.Body.CanSeek)
            {
                // To avoid blocking on the stream, we asynchronously read everything
                // into a buffer, and then seek back to the beginning.
                request.EnableBuffering();
                Debug.Assert(request.Body.CanSeek);

                // no timeout configuration on this? or does that happen at another layer?
                await request.Body.DrainAsync(CancellationToken.None);

                request.Body.Seek(0L, SeekOrigin.Begin);
            }

            using (var streamReader = context.ReaderFactory(request.Body, encoding))
                using (var jsonReader = new JsonTextReader(streamReader))
                {
                    // need to configure these properties as is done in
                    // HL7.Fhir.SerializationUtil.JsonReaderFromJsonText()
                    jsonReader.DateParseHandling  = DateParseHandling.None;
                    jsonReader.FloatParseHandling = FloatParseHandling.Decimal;

                    try
                    {
                        if (FhirMajorVersion == Common.Enums.FhirVersion.Stu3)
                        {
                            var resource = new R4Serialization.FhirJsonParser().Parse <R4Model.Resource>(jsonReader);
                            return(InputFormatterResult.Success(resource));
                        }
                        else if (FhirMajorVersion == Common.Enums.FhirVersion.R4)
                        {
                            var resource = new Stu3Serialization.FhirJsonParser().Parse <Stu3Model.Resource>(jsonReader);
                            return(InputFormatterResult.Success(resource));
                        }
                        else
                        {
                            throw new FhirFatalException(System.Net.HttpStatusCode.BadRequest, "Unable to resolve which major version of FHIR is in use.");
                        }
                    }
                    catch (FormatException exception)
                    {
                        throw new FhirFatalException(System.Net.HttpStatusCode.BadRequest, "Body parsing failed: " + exception.Message);
                    }
                }
        }
        public override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            Type type = context.ModelType;

            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            HttpRequest request = context.HttpContext.Request;

            if (request == null)
            {
                throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest);
            }

            // If content length is 0 then return default value for this type
            RequestHeaders contentHeaders = request.GetTypedHeaders();
            object         defaultValue   = GetDefaultValueForType(type);

            if (contentHeaders == null || contentHeaders.ContentLength == 0)
            {
                return(Task.FromResult(InputFormatterResult.Success(defaultValue)));
            }

            try
            {
                Func <ODataDeserializerContext> getODataDeserializerContext = () =>
                {
                    return(new ODataDeserializerContext
                    {
                        Request = request,
                    });
                };

                Action <Exception> logErrorAction = (ex) =>
                {
                    ILogger logger = context.HttpContext.RequestServices.GetService <ILogger>();
                    if (logger == null)
                    {
                        throw ex;
                    }

                    logger.LogError(ex, String.Empty);
                };

                List <IDisposable> toDispose = new List <IDisposable>();

                ODataDeserializerProvider deserializerProvider = request.GetRequestContainer().GetRequiredService <ODataDeserializerProvider>();

                object result = ODataInputFormatterHelper.ReadFromStream(
                    type,
                    defaultValue,
                    request.GetModel(),
                    GetBaseAddressInternal(request),
                    new WebApiRequestMessage(request),
                    () => ODataMessageWrapperHelper.Create(request.Body, request.Headers, request.GetODataContentIdMapping(), request.GetRequestContainer()),
                    (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType),
                    (objectType) => deserializerProvider.GetODataDeserializer(objectType, request),
                    getODataDeserializerContext,
                    (disposable) => toDispose.Add(disposable),
                    logErrorAction);

                foreach (IDisposable obj in toDispose)
                {
                    obj.Dispose();
                }

                return(Task.FromResult(InputFormatterResult.Success(result)));
            }
            catch (Exception ex)
            {
                context.ModelState.AddModelError(context.ModelName, ex, context.Metadata);
                return(Task.FromResult(InputFormatterResult.Failure()));
            }
        }
示例#16
0
        public async override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            var request = context.HttpContext.Request;

            using (var streamReader = context.ReaderFactory(request.Body, encoding))
            {
                using (var jsonReader = new JsonTextReader(streamReader))
                {
                    jsonReader.ArrayPool  = _charPool;
                    jsonReader.CloseInput = false;

                    var jsonMergePatchType = context.ModelType;
                    var container          = (IList)null;

                    if (ContainerIsIEnumerable(context))
                    {
                        jsonMergePatchType = context.ModelType.GenericTypeArguments[0];
                        var listType            = typeof(List <>);
                        var constructedListType = listType.MakeGenericType(jsonMergePatchType);
                        container = (IList)Activator.CreateInstance(constructedListType);
                    }
                    var modelType = jsonMergePatchType.GenericTypeArguments[0];


                    var jsonSerializer = CreateJsonSerializer();
                    try
                    {
                        var jToken = await JToken.LoadAsync(jsonReader);

                        switch (jToken)
                        {
                        case JObject jObject:
                            if (container != null)
                            {
                                throw new ArgumentException("Received object when array was expected");                                         //This could be handled by returnin list with single item
                            }
                            var jsonMergePatchDocument = CreatePatchDocument(jsonMergePatchType, modelType, jObject, jsonSerializer);
                            return(await InputFormatterResult.SuccessAsync(jsonMergePatchDocument));

                        case JArray jArray:
                            if (container == null)
                            {
                                throw new ArgumentException("Received array when object was expected");
                            }

                            foreach (var jObject in jArray.OfType <JObject>())
                            {
                                container.Add(CreatePatchDocument(jsonMergePatchType, modelType, jObject, jsonSerializer));
                            }
                            return(await InputFormatterResult.SuccessAsync(container));
                        }

                        return(await InputFormatterResult.FailureAsync());
                    }
                    catch (Exception ex)
                    {
                        context.ModelState.TryAddModelError(context.ModelName, ex.Message);
                        return(await InputFormatterResult.FailureAsync());
                    }
                    finally
                    {
                        ReleaseJsonSerializer(jsonSerializer);
                    }
                }
            }
        }
示例#17
0
 public Task <InputFormatterResult> ReadAsync(InputFormatterContext context)
 {
     return(InputFormatterResult.SuccessAsync(null));
 }
示例#18
0
 public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
 {
     using (var sr = new StreamReader(context.HttpContext.Request.Body))
         return(await InputFormatterResult.SuccessAsync(await sr.ReadToEndAsync().ConfigureAwait(false)).ConfigureAwait(false));
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            var xmlDoc = await XDocument.LoadAsync(context.HttpContext.Request.Body, LoadOptions.None, CancellationToken.None);

            return(InputFormatterResult.Success(xmlDoc));
        }
示例#20
0
 public override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
 {
     return(Task.FromResult(InputFormatterResult.Success(null)));
 }
示例#21
0
 public override async Task<InputFormatterResult> ReadRequestBodyAsync(
     InputFormatterContext context,
     Encoding encoding)
 {
     if (context == null)
     {
         throw new ArgumentNullException(nameof(context));
     }
     if (encoding == null)
     {
         throw new ArgumentNullException(nameof(encoding));
     }
     var request = context.HttpContext.Request;
     var suppressInputFormatterBuffering = options?.SuppressInputFormatterBuffering ?? false;
     if (!request.Body.CanSeek && !suppressInputFormatterBuffering)
     {
         // JSON.Net does synchronous reads. In order to avoid blocking on the stream, we asynchronously
         // read everything into a buffer, and then seek back to the beginning.
         request.EnableBuffering();
         Debug.Assert(request.Body.CanSeek);
         await request.Body.DrainAsync(CancellationToken.None);
         request.Body.Seek(0L, SeekOrigin.Begin);
     }
     using (var streamReader = context.ReaderFactory(request.Body, encoding))
     {
         using (var jsonReader = new JsonTextReader(streamReader))
         {
             jsonReader.ArrayPool = charPool;
             jsonReader.CloseInput = false;
             var successful = true;
             Exception exception = null;
             void ErrorHandler(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs eventArgs)
             {
                 successful = false;
                 var path = eventArgs.ErrorContext.Path;
                 var key = ModelNames.CreatePropertyModelName(context.ModelName, path);
                 context.ModelState.TryAddModelError(key, $"Invalid value specified for {path}");
                 eventArgs.ErrorContext.Handled = true;
             }
             var type = context.ModelType;
             var jsonSerializer = CreateJsonSerializer();
             jsonSerializer.Error += ErrorHandler;
             object model;
             try
             {
                 model = jsonSerializer.Deserialize(jsonReader, type);
             }
             finally
             {
                 // Clean up the error handler since CreateJsonSerializer() pools instances.
                 jsonSerializer.Error -= ErrorHandler;
                 ReleaseJsonSerializer(jsonSerializer);
             }
             if (successful)
             {
                 if (model == null && !context.TreatEmptyInputAsDefaultValue)
                 {
                     // Some nonempty inputs might deserialize as null, for example whitespace,
                     // or the JSON-encoded value "null". The upstream BodyModelBinder needs to
                     // be notified that we don't regard this as a real input so it can register
                     // a model binding error.
                     return InputFormatterResult.NoValue();
                 }
                 else
                 {
                     return InputFormatterResult.Success(model);
                 }
             }
             if (!(exception is JsonException || exception is OverflowException))
             {
                 var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception);
                 exceptionDispatchInfo.Throw();
             }
             return InputFormatterResult.Failure();
         }
     }
 }
示例#22
0
        public async Task <InputFormatterResult> ReadAsync(InputFormatterContext context)
        {
            var text = await context.HttpContext.Request.Body.ReadAllTextAsync();

            return(InputFormatterResult.Success(text));
        }
示例#23
0
        /// <inheritdoc />
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(
            InputFormatterContext context,
            Encoding encoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

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

            var request = context.MazeContext.Request;

            if (!request.Body.CanSeek)
            {
                // JSON.Net does synchronous reads. In order to avoid blocking on the stream, we asynchronously
                // read everything into a buffer, and then seek back to the beginning.
                request.EnableBuffering();
                Debug.Assert(request.Body.CanSeek);

                await request.Body.DrainAsync(CancellationToken.None);

                request.Body.Seek(0L, SeekOrigin.Begin);
            }

            using (var streamReader = context.ReaderFactory(request.Body, encoding))
            {
                using (var jsonReader = new JsonTextReader(streamReader))
                {
                    jsonReader.ArrayPool  = _charPool;
                    jsonReader.CloseInput = false;

                    var       successful = true;
                    Exception exception  = null;
                    void ErrorHandler(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs eventArgs)
                    {
                        successful = false;

                        // Handle path combinations such as "" + "Property", "Parent" + "Property", or "Parent" + "[12]".
                        var key = eventArgs.ErrorContext.Path;

                        if (!string.IsNullOrEmpty(context.ModelName))
                        {
                            if (string.IsNullOrEmpty(eventArgs.ErrorContext.Path))
                            {
                                key = context.ModelName;
                            }
                            else if (eventArgs.ErrorContext.Path[0] == '[')
                            {
                                key = context.ModelName + eventArgs.ErrorContext.Path;
                            }
                            else
                            {
                                key = context.ModelName + "." + eventArgs.ErrorContext.Path;
                            }
                        }

                        var modelStateException = WrapExceptionForModelState(eventArgs.ErrorContext.Error);

                        context.ModelState.TryAddModelError(key, modelStateException, context.Metadata);

                        _logger.JsonInputException(eventArgs.ErrorContext.Error);

                        exception = eventArgs.ErrorContext.Error;

                        // Error must always be marked as handled
                        // Failure to do so can cause the exception to be rethrown at every recursive level and
                        // overflow the stack for x64 CLR processes
                        eventArgs.ErrorContext.Handled = true;
                    }

                    var type           = context.ModelType;
                    var jsonSerializer = CreateJsonSerializer();
                    jsonSerializer.Error += ErrorHandler;
                    object model;
                    try
                    {
                        model = jsonSerializer.Deserialize(jsonReader, type);
                    }
                    finally
                    {
                        // Clean up the error handler since CreateJsonSerializer() pools instances.
                        jsonSerializer.Error -= ErrorHandler;
                        ReleaseJsonSerializer(jsonSerializer);
                    }

                    if (successful)
                    {
                        if (model == null && !context.TreatEmptyInputAsDefaultValue)
                        {
                            // Some nonempty inputs might deserialize as null, for example whitespace,
                            // or the JSON-encoded value "null". The upstream BodyModelBinder needs to
                            // be notified that we don't regard this as a real input so it can register
                            // a model binding error.
                            return(InputFormatterResult.NoValue());
                        }
                        else
                        {
                            return(InputFormatterResult.Success(model));
                        }
                    }

                    if (!(exception is JsonException || exception is OverflowException))
                    {
                        var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception);
                        exceptionDispatchInfo.Throw();
                    }

                    return(InputFormatterResult.Failure());
                }
            }
        }
示例#24
0
        /// <summary>
        /// Handle application/octet-stream row data.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            var contentType = context.HttpContext.Request.ContentType;

            if (contentType != "application/octet-stream" && contentType != "application/gzip")
            {
                return(await InputFormatterResult.FailureAsync());
            }

            IServiceProvider serviceProvider = context.HttpContext.RequestServices;
            var logger  = serviceProvider.GetService(typeof(ILogger <DecFormatter>)) as ILogger;
            var request = context.HttpContext.Request;


            var buffer = new MemoryStream();

            if (contentType == "application/octet-stream")
            {
                logger.LogDebug("解密資料");
                Thread.Sleep(100);

                // 載入私鑰.
                var dec_cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
                dec_cipher.Init(false, this.priKey); // false表示解密

                // 分段解密.
                byte[] block = new byte[128];
                while (request.Body.Read(block, 0, block.Length) == block.Length)
                {
                    var decrypt = dec_cipher.DoFinal(block);
                    buffer.Write(decrypt, 0, decrypt.Length);
                }
            }
            else // "application/gzip" case
            {
                logger.LogDebug("不解密資料");
                await request.Body.CopyToAsync(buffer);
            }

            // 重置位置才能讓GZipStream讀取到資料
            buffer.Seek(0, SeekOrigin.Begin);
            //logger.LogDebug("stream length: " + buffer.ToArray().Length);

            // Decompress row data and decode it by base64, return origin string.
            var decompressor = (Stream) new GZipStream(buffer, CompressionMode.Decompress, true);
            var ms           = new MemoryStream();
            await decompressor.CopyToAsync(ms);

            var base64Str = System.Text.Encoding.UTF8.GetString(ms.ToArray());
            var originStr = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(base64Str));

            if (string.IsNullOrEmpty(originStr))
            {
                logger.LogError("Got empty result.");
            }
            // 資源回收
            if (decompressor != null)
            {
                decompressor.Dispose();
            }
            if (ms != null)
            {
                ms.Dispose();
            }
            if (buffer != null)
            {
                buffer.Dispose();
            }
            return(await InputFormatterResult.SuccessAsync(originStr));
        }