/// <summary> /// Handle text/plain or no content type for string results /// Handle application/octet-stream for byte[] results /// </summary> /// <param name="context"></param> /// <returns></returns> public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) { var request = context.HttpContext.Request; var contentType = context.HttpContext.Request.ContentType; if (string.IsNullOrEmpty(contentType) || contentType == "text/plain") { using (var reader = new StreamReader(request.Body)) { var content = await reader.ReadToEndAsync(); return(await InputFormatterResult.SuccessAsync(content)); } } if (contentType == "application/octet-stream") { using (var ms = new MemoryStream(2048)) { await request.Body.CopyToAsync(ms); var content = ms.ToArray(); return(await InputFormatterResult.SuccessAsync(content)); } } return(await InputFormatterResult.FailureAsync()); }
/// <inheritdoc /> public override Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var selectedEncoding = SelectCharacterEncoding(context); if (selectedEncoding == null) { var message = Resources.FormatUnsupportedContentType( context.HttpContext.Request.ContentType); var exception = new UnsupportedContentTypeException(message); context.ModelState.AddModelError(context.ModelName, exception, context.Metadata); return(InputFormatterResult.FailureAsync()); } return(ReadRequestBodyAsync(context, selectedEncoding)); }
/// <inheritdoc /> public 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; using (var streamReader = context.ReaderFactory(request.Body, encoding)) { using (var jsonReader = new JsonTextReader(streamReader)) { jsonReader.ArrayPool = _charPool; jsonReader.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); _logger.JsonInputException(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) { return(InputFormatterResult.SuccessAsync(model)); } return(InputFormatterResult.FailureAsync()); } } }