C# 缺少内容类型边界

标签 c# .net-core boundary media-type

我正在使用 RestEase 客户端库从一项服务向另一项服务发出请求。 它的界面是这样的

public interface IImportService1ApiClient
{
    [Put]
    [Header("Content-Type", "multipart/form-data")]
    Task<CreateValidationJobResponse> ImportZip([Body] byte[] zipByteArray);
}

和端点(.Net Core 1.1,Web Api):

    [HttpPut()]
    [Consumes("multipart/form-data")]
    public async Task<IActionResult> ImportZip()
    {
         var zipFile = HttpContext.Request.Form.Files.FirstOrDefault();
     ...

所以我可以发出请求,但是当我尝试从文件集合中获取文件时出现异常

System.IO.InvalidDataException: Missing content-type boundary.

堆栈跟踪:

 Connection id "0HL8CNQ0E4M94": An unhandled exception was thrown by the application.
System.IO.InvalidDataException: Missing content-type boundary.
   at Microsoft.AspNetCore.Http.Features.FormFeature.GetBoundary(MediaTypeHeaderValue contentType, Int32 lengthLimit)
   at Microsoft.AspNetCore.Http.Features.FormFeature.<InnerReadFormAsync>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Http.Features.FormFeature.ReadForm()
   at RODIX.Tacs.Services.Import.Api.Controllers.TacsLegacyImportController.<ImportZip>d__3.MoveNext() in C:\Users\borov\Source\Repos\Rodix.Tacs\Rodix.Tacs\services\RODIX.ImportService\src\RODIX.Tacs.Services.Import.Api\Controllers\TacsLegacyImportController.cs:line 32
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.<RequestProcessingAsync>d__2.MoveNext()

但是当用 Postman 做同样的事情时一切正常。 那么边界实际上是什么,为什么我会遗漏它以及如果确实需要如何添加它?

最佳答案

如果您只是上传一个文件,为什么不直接抓取 Request.Body 流:

[HttpPost()]
[Consumes("application/zip")]
[Consumes("application/octet-stream")]
public async Task<IActionResult> ImportZip()
{
    using (var stream = new MemoryStream())
    {
        await Request.Body.CopyToAsync(stream);
    }

    // do whatever with the file...
}

我想你也可以这样定义它:

[HttpPost()]
[Consumes("application/zip")]
[Consumes("application/octet-stream")]
public async Task<IActionResult> ImportZip([FromBody] Stream bodyStream)
{
    using (var stream = new MemoryStream())
    {
        await bodyStream.CopyToAsync(stream);
    }

    // do whatever with the file...
}

关于C# 缺少内容类型边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46606403/

相关文章:

Python:跨文件 block 边界的正则表达式匹配

python - 稀疏矩阵模式上的 Scipy 边界条件

c# - 如何在 C# 中使 Dropdownlist 只读

c# - 驱动程序中缺少 MongoDB 驱动程序(查询生成器)?

c# - JSON.Net 结构序列化差异

c# - 使用 fluentmigrator 运行 sql 脚本

azure - 为什么使用自定义文件扩展名上传到 azure blob 容器的 gzip 压缩文件会通过生成的 sas 下载为 .gz?

javascript - 在 headless 浏览器中使用 Blazor 与 C# 一起运行 Javascript

c# - 在 Razor 组件 (Blazor) 中渲染 Razor 局部 View

testing - 边界值分析 - 何时使用二值或三值?