我想将文件上传到asp net core web api controller动作方法。我发送内容类型为“application / octet-stream”。我创建了名为StreamInputFormatter的自定义输入格式化程序。 streaminputformatter被调用,但控制器中的action方法没有被调用?和我的错误
“InvalidOperationException:此流不支持超时。”
StreamInputFormatter:
public class StreamInputFormatter : IInputFormatter
{
public bool CanRead(InputFormatterContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var contentType = context.HttpContext.Request.ContentType;
if (contentType == "application/octet-stream")
{
return true;
}
return false;
}
public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var memoryStream = new MemoryStream();
context.HttpContext.Request.Body.CopyTo(memoryStream);
return InputFormatterResult.SuccessAsync(memoryStream);
}
}
控制器操作方法:
[HttpPost("{documentType}")]
public async Task<IActionResult> CreateJob(string documentType, [FromBody]Stream template)
{
}
答案 0 :(得分:2)
由于DefaultObjectValidator
迭代了不受支持的Stream
属性,因此听到您收到此错误(有关详细信息,请参阅此issue)。
要跳过流模型验证,您可以添加
services.AddMvc(options =>
{
...
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Stream)));
});
到你的配置。
答案 1 :(得分:1)
对于正在寻找完整示例的任何人,以下内容可能会有所帮助:
Startup.cs
services.AddMvc(options =>
{
options.InputFormatters.Add(new StreamInputFormatter());
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Stream)));
}
StreamInputFormatter.cs
public class StreamInputFormatter : IInputFormatter
{
// enter your list here...
private readonly List<string> _allowedMimeTypes = new List<string>
{ "application/pdf", "image/jpg", "image/jpeg", "image/png", "image/tiff", "image/tif", "application/octet-stream" };
public bool CanRead(InputFormatterContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var contentType = context.HttpContext.Request.ContentType;
if (_allowedMimeTypes.Any(x => x.Contains(contentType)))
{
return true;
}
return false;
}
public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
// enable stream rewind or you won't be able to read the file in the controller
var req = context.HttpContext.Request;
req.EnableRewind();
var memoryStream = new MemoryStream();
context.HttpContext.Request.Body.CopyTo(memoryStream);
req.Body.Seek(0, SeekOrigin.Begin);
return InputFormatterResult.SuccessAsync(memoryStream);
}
}
然后是控制器:
public class FileController : BaseController
{
[HttpPost("customer/{customerId}/file", Name = "UploadFile")]
[SwaggerResponse(StatusCodes.Status201Created, typeof(UploadFileResponse))]
[Consumes("application/octet-stream", new string[] { "application/pdf", "image/jpg", "image/jpeg", "image/png", "image/tiff", "image/tif"})]
public async Task<IActionResult> UploadFile([FromBody] Stream file, [FromRoute] string customerId, [FromQuery] FileQueryParameters queryParameters)
{
// file processing here
}
}