Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用AngularJS上载多个文件时的奇怪行为_C#_Asp.net Mvc_Angularjs - Fatal编程技术网

C# 使用AngularJS上载多个文件时的奇怪行为

C# 使用AngularJS上载多个文件时的奇怪行为,c#,asp.net-mvc,angularjs,C#,Asp.net Mvc,Angularjs,我有一个使用AngularJS的ASP MVC4项目。有一个表单,包含数据和任意数量的文件,需要发布到服务器。当我尝试发送多个文件时,ASP MVC无法将文件绑定到我的对象。发送单个文件时,表单和文件都会正确绑定到我的对象 //multiple files action public ActionResult Send(myModel model, IEnumerable<HttpPostedFileBase> files) { //"model" contains the

我有一个使用AngularJS的ASP MVC4项目。有一个表单,包含数据和任意数量的文件,需要发布到服务器。当我尝试发送多个文件时,ASP MVC无法将文件绑定到我的对象。发送单个文件时,表单和文件都会正确绑定到我的对象

//multiple files action
public ActionResult Send(myModel model, IEnumerable<HttpPostedFileBase> files)
{
     //"model" contains the correct data
     //"files" is initialized but has Count = 0
     return View();
}

//single file action
public ActionResult SendSingle(myModel model, HttpPostedFileBase files)
{
     //"model" contains the correct data
     //"files" contains the selected file
     return View();
}
服务很明显吗?设置标题并发送数据相关代码:

sendData = function(formData) {
    $q.all({
        //ResponseData: $http.post('MyController/SendSingle', formData, { 
        ResponseData: $http.post('MyController/Send', formData, { 
           transformRequest: angular.identity,
           headers: { 'Content-Type': undefined }
        })
    }).then(...).catch(...);
}
真正奇怪的是,IEnumerable文件被实例化,但不包含Count=0的文件。通过检查服务器上的请求对象,我可以在Request.files属性中看到所有上载的文件。ModelState在files参数中附加了一个错误,这是由于尝试将字符串强制转换到HttpPostedFileBase时出现异常引起的

为什么服务器不自动绑定文件IEnumerable,即为什么服务器不自动绑定二进制内容

编辑:
这将是一个反复出现的主题,因此我将在这里添加此信息。我尝试将内容设置为多部分/表单数据,因为这是在ASP MVC中发布数据和文件的标准方式。但是,这根本不起作用:表单数据和文件都不会自动绑定。我的模型属性都为null,files对象也为null,而不是initialized,但没有元素。很明显AngularJS在这个内容类型头上有一些问题。另一方面,jQuery也是如此,您需要设置contentType:false、processData:false以发布表单数据和二进制内容

看起来您正在取消设置内容类型,请尝试将其设置为多部分/表单数据。这将指导服务器如何解析发布的内容。

如果您使用的是常规控制器,您可以尝试使用以下方法:

    foreach (string key in Request.Files)
    {
        HttpPostedFileBase file = Request.Files[key];
    }
如果您正在使用WebAPI:

if (Request.Content.IsMimeMultipartContent())
            {
                var rootPath = TMP_SAVE_PATH; //some path
                var provider = new MultipartFormDataStreamProvider(rootPath);

                await Request.Content.ReadAsMultipartAsync(provider);

                foreach (var fileData in provider.FileData)
                {
                    var fileName = fileData.Headers.ContentDisposition.FileName.TrimEnd(new char[] { '\\' }).Trim(new char[] { '"' });
                    File.Move(fileData.LocalFileName, fileName); //move to some location
                }
            }

我试图重现您的问题,但它对我有效,所以我将只发布我的代码。我希望这有助于:

html:

控制器:

//AngularJS controller
var fData = new FormData();
fData.append("Prop1", "value1");
fData.append("Prop2", "value2");

var fileInputs = getFormFileInputs();
for (var i = 0; i < fileInputs.length; i++) {
    fData.append("files", fileInputs[i].files[0]);
}

MyService.sendData(fData);
public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Upload(TestModel model, IEnumerable<HttpPostedFileBase> files)
    {
        return Json(new { files = files.ToList().Select(x => x.FileName), model = model });
    }       
}

当您在控制器中签入Request.Files时,它会做同样的事情吗?@Sam9291您的意思是什么?我已经说过我可以在Request.files中看到上传的文件。我怀疑这行代码fData.appendfiles,fileInputs[I].files[0];。当只有一个文件时,这会起作用,但如果多个文件和所有文件都附加到同一个变量,则可能会产生问题。为什么标题:{‘内容类型’:未定义}不应该是:multipart/form-data@HarishR,请查看我的编辑。这是我尝试的第一个标题值。AngularJS有一些问题。请参阅我的编辑。谢谢你的评论,但我的问题与如何获取文件无关?但是为什么我的IEnumerable没有正确绑定?在这种情况下,您可以尝试重写模型绑定器的BindModel方法,以查看传递到那里的内容。如果需要文件未绑定到模型的原因,还可以反编译DefaultModelBinder类。你可以找到更多关于模型绑定的信息,这让人困惑。。。它确实有效,但没有。我甚至不能开始理解发生了什么。@AndreiV程序员生活的奥秘:有时也发生在我身上:
public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Upload(TestModel model, IEnumerable<HttpPostedFileBase> files)
    {
        return Json(new { files = files.ToList().Select(x => x.FileName), model = model });
    }       
}