HttpContext.Current.Request.Files总是为空。

3

我看到很多WebAPI接受文件的例子。然而,无论我尝试什么方法,HttpContext.Current.Request.Files都没有包含我通过Postman发布到Web API的文件。 (我也通过控制台应用程序发布了该图像并获得了相同的结果)

[HttpPost]
[ActionName("Post")]
[ResponseType(typeof(PeliquinApiRsp))]
    public IHttpActionResult Post(int personId)
    {
        var empPicture = PeliquinIOC.Resolve<IEmpPictureBL>(UserId, UserName, PropertyCode);

        if (!(IsAllowed(SysPrivConstants.SYSPRIV__TYPE_PERSONNEL, SysPrivConstants.SYSPRIV__FUNC_PERSONNEL_CARDHOLDER, SysPrivConstants.SYSPRIV__LEVEL_FULL)))
            return (Unauthorized());

        var apiRsp = new PeliquinApiRsp();

        var httpRequest = HttpContext.Current.Request;

        if (httpRequest.Files.Count == 0)
        return BadRequest();

        empPicture.Post(httpRequest.Files[0].InputStream, personId);

        apiRsp.SetStatus();
        apiRsp.SetData("EmpPicture");

        return (Ok(apiRsp));
    }

这是一个非常简单的方法。我一直在使用Postman来发布二进制.jpg文件。我设置了content-type =“multipart/form-data”。我的代码没有抛出任何错误,除了.Files = 0之外。

我在WebApiConfig中有一些其他的设置,用于处理API的其余部分,但为了保险起见,我将它们包括在内,以及这个特定方法的路由:

config.Formatters.Remove( config.Formatters.XmlFormatter );
config.Formatters.JsonFormatter.SupportedMediaTypes.Add( new MediaTypeHeaderValue( "application/json" ) );
config.Formatters.FormUrlEncodedFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));


config.Routes.MapHttpRoute(
            name: "EmpPicturePost",
            routeTemplate: "api/EmpPicture/{personId}",
            defaults: new { controller = "EmpPicture", action = "Post" },                
            constraints: new { personId = @"^\d+$", httpMethod = new HttpMethodConstraint(HttpMethod.Post, HttpMethod.Options) }
        );

我已经陷入困境,试图找出为什么这么简单的东西却无法工作。我尝试了很多其他更适合MVC方式的方法,但这不是一个MVC应用程序,并且它们会产生不同的错误。感谢任何帮助。


你是使用 form-data 单选按钮还是只是设置了 content-type 标头? - Paul Abbott
我正在使用二进制单选按钮,并在本地驱动器上选择一个 .jpg 文件。我还设置了内容类型标头。 - Jonathan Hansen
我还创建了一个全新的 Web API,并使用内置的默认 ValuesController 尝试将图像 POST 到它,结果出现了相同的问题。 - Jonathan Hansen
3个回答

1

我也曾经为这个问题苦苦挣扎,但最终找到了解决方法。在我的情况下,我从iOS应用程序调用端点时文件总是为空。我发现我需要拥有一个与表单中文件字段名称匹配的http头,因此请求必须具有例如以下的http头:

file: newImage.jpg

在请求体中,您需要类似以下内容:

Content-Disposition: form-data; name="file"; filename="newImage.jpg"
Content-Type: image/jpg

请注意,这不是一个有效的请求,只是一个片段。您仍需要更多的HTTP标头以及主体字段周围的边界。我的观点是,要求似乎是HTTP标头键和表单字段名称匹配且两者都存在。

这是我在Postman中遇到的问题。我选择了一个文件,然后将文件名从“值”文本框复制/粘贴到“键”文本框中,结果插入了一个新行,导致文件名与实际文件名不匹配。 - Brad

0

我怀疑你的问题根本原因很可能是你在帖子中提到的这个 -

我一直在使用Postman发布二进制.jpg文件。 我已经设置了 content-type =“multipart / form-data”

你不应该在postman工具中明确这样做。 Postman工具足够智能,可以自动检测Content-Type。 请参见我的this答案以帮助您更好地理解。

Content-Type设置为“multipart / form-data”涉及多个部分的边界的复杂概念,详细信息请参见here。 在此情况下,postman工具会自动为您完成设置边界的繁重工作,这就是为什么它不希望您在此处明确设置content-type的原因。


0

我认为Postman无法填充HttpContext.Current.Request.Files集合。我们通过使用以下方法解决了这个问题: await Request.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

Ivo


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接