我有一个AngularJS + ASP.NET MVC 5应用程序,正在尝试实现单个文件上传。
在客户端,我有以下代码:
api.uploadFileV2 = function (alias, file, fnSuccess, fnError) {
var formData = new FormData();
formData.append(file.name, file);
$http.post('/api/V2/Upload/' + alias, formData, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
}).success(function (data) {
if (fnSuccess)
fnSuccess(data);
}).error(function (data) {
if (fnError)
fnError(data);
});
}
file参数是通过单击按钮调用的函数传入的,当在Chrome和Edge中执行时,我可以看到file参数实际上是一个文件对象。
回到服务器端,我有一条到控制器的路由,定义如下:
config.Routes.MapHttpRoute(
name: "V2UploadApi",
routeTemplate: "api/V2/Upload/{alias}/{id}",
defaults: new { controller = "Upload", id = RouteParameter.Optional }
);
回到服务器端,我有了我的UploadController,其中定义了以下方法:
public JArray Upload(string Alias)
{
JArray results = new JArray();
try
{
HttpRequest r = HttpContext.Current.Request;
HttpFileCollection c = r.Files;
foreach (var item in r.Files)
{
string theType = item.GetType().Name;
}
}
...
}
注意:使用Alias参数进行奇数方法签名的原因是,最终上载的文件将由Powershell脚本管理,该脚本的选择和安全级别取决于别名值。
在执行UploadController.Upload方法后,我看到了期望的Alias值。
我看不到我的文件对象。因此var item不会像我期望的那样解析为HttpPostedFile类型,而是解析为string type,因此变量“ theType”包含“ string”而不是“ HttpPostedFile “。 HttpFileCollection实际上并不包含HttpPostedFile对象的集合,并且尝试将集合结果中的项目强制转换为HttpPostedFile类型,导致抛出异常。
什么原因可能导致服务器端出现这种奇怪的行为,我该怎么做才能纠正它?
上传文件基本没什么困难,所以我必须缺少明显的东西-问题是我没有看到它。
因此,在另一个调试会话之后,我将代码更改为:
HttpRequest r = HttpContext.Current.Request;
HttpFileCollection c = r.Files;
foreach (string key in r.Files.Keys)
{
var item = r.Files[key];
string theType = item.GetType().Name;
}
此代码不仅有效,而且还吸引了我的老式编码风格,即不要懒惰地使用var将所有内容完全留给编译器。我错误地认为HttpFileCollection的枚举数可用于(string)Key /(HttpPostedFile)Value对,但是显然我错了。