将带有 XMLHttpRequest 的 Javascript FormData 提交到 WebForms Web API 控制器类 2.1 抛出不支持的媒体类型

问题描述

背景

我们有自己的 javascript 框架,它与服务器代码通信以下载文件上传文件、执行操作、生成文档等。服务器代​​码目前是 WebForms 4.5,但是,它被指定迁移到 .NET Core Razor页面/Web API。我想在我们的 javascript 框架中尽可能少地更新,以便它通过适当的 web api 调用与服务器通信,以便在服务器更新到最新框架时不必更改。

目前,客户端 javascript 只是将 FormData 对象发布到 default.aspx。 WebForms 代码隐藏使用 HttpContext.Current.Request.Form[ "" ] 访问字符串变量并将它们解析为 JObject 变量,最终处理请求。 javascript 当前使用 FormData,因为该代码与执行下载、上传和命令的不同操作共享,并且从我读过的内容来看,文件上传需要 FormData .

为了完成帖子,客户端 javascript 使用 XMLHttpRequest 对象。从实验和搜索 stackoverflow 来看,使用 $.ajax 无法下载文件,唯一似乎可靠的模式是使用 XMLHttpRequest(下面的列表中省略了代码)。

代码

我的 C# ASP.NET 4.5* WebForms 项目中有以下 ApiController 类作为 Web Api 控制器:

public class KatAppEndpointsController : ApiController
{
    public class KatAppEndpointParameters
    {
        public string View { get; set; }
        public string Inputs { get; set; }
        public string Configuration { get; set; }
    }

    [HttpPost]
    [Route( "api/files/download" )]
    public string DownloadFile( KatAppEndpointParameters parameters )
    {
        return "Success";
    }
}

请注意,上面是下载文件的重构后面的 default.aspx 代码的开始。因此,return "Success"; 目前只是占位符代码,需要替换为实际下载文件

我的 javascript 框架有以下内容

var fd = new FormData();
fd.append("View","ViewName" );
fd.append("Inputs",JSON.stringify({ Input1: "Value1",Input2: "Value2" }));
fd.append("Configuration",JSON.stringify( { CustomOptions: "CustomValue" }));

var xhr = new XMLHttpRequest();
xhr.open("POST","api/files/download",true);
// xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

xhr.onreadystatechange = function (): void {
    // omitted code to set xhr.responseType
};

xhr.onload = function (): void {
    // omitted code to process results or download file
};

xhr.send(fd);

观察到的行为

鉴于此代码发生了一些事情:

  1. 照原样,我再也没有回到我的 web api 控制器,我立即收到了 415 Media Type Unsupported 响应。

  2. 如果我取消对 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 的注释,我将返回到服务器 web api 代码,但我的参数对象具有所有 null 属性值,而在 HttpContext.Current.Request.Form 中只有一个键 (------WebKitFormBoundaryT6DA5YOQpROCIxxU\r\nContent-disposition: form-data; name) 具有大 string 值,由 WebKitFormBoundary 标记分隔的三个“部分”。

  3. 如果我将 setRequestHeader 注释掉,但在服务器上,从方法签名中删除 KatAppEndpointParameters 参数,我将返回到服务器 web api代码,并且 HttpContext.Current.Request.Form 正确具有 View/Inputs/Configuration 的三个键/值。

问题

  1. 我希望能够对 parameters 变量进行模型绑定。在 WebForms 4.5* 中,我没有访问 [FromForm] 属性,就像建议的许多问题一样。这必须仅在 mvc web api 项目中可用。

  2. 更好的是,我想将 InputsConfiguration 更改为自动绑定到模型类,或者至少更改为 JObject。显然,作为字符串,我只会做一个 JObject.Parse,但如果可能的话,我想要前一个选项。

这是可能的还是上面的场景 3 是唯一可能的解决方案 - 删除方法参数并在每个控制器操作方法中手动执行类似 JObject.Parse( Request.Form[ "" ] ) 的操作?

注意:我可以重构此代码以不使用 FormData 而是尝试简单地使用/绑定到常规 json 字符串数据,但是对于我也必须转换的“UploadFile”操作方法,我相信 FormData 是必需的,所以那时我可能会遇到同样的问题。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)