我正在将项目从ASP.NET RC1迁移到ASP.NET Core 1.0。
我有一个允许用户上传一个或多个文件的视图,我使用Jquery Ajax发布。我还在同一篇文章中序列化并发布了一些设置。
以下所有内容均适用于RC1(和pre-asp.net核心):
JS:
$('#submit').click(function () {
var postData = $('#fields :input').serializeArray();
var fileSelect = document.getElementById('file-select');
var files = fileSelect.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append('file' + i, files[i]);
}
$.each(postData, function (key, input) {
data.append(input.name, input.value);
});
var url = '/ajax/uploadfile';
$.ajax({
url: url,
type: "POST",
contentType: false,
processData: false,
cache: false,
data: data,
success: function (result) {
alert('success');
},
error: function () {
alert('error');
}
});
});
控制器:
public IActionResult UploadFile(UploadFileModel model)
{
var result = new JsonResultData();
try
{
if (Request.Form.Files.Count > 0)
{
IFormFile file = Request.Form.Files[0];
//etc
}
}
}
因此上述功能不再起作用,没有上传文件且没有绑定模型。
我设法修复了一半的问题所以现在我可以让模型与以下代码绑定。但是,控制器仍会在Request.Files
上给我一个例外。我添加了'headers'属性,并使用serializeObject
(自定义方法)。在控制器中我添加了FromBody
。
JS:
$('#submit').click(function () {
var postData = $('#fields :input').serializeArray();
var fileSelect = document.getElementById('file-select');
var files = fileSelect.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append('file' + i, files[i]);
}
$.each(postData, function (key, input) {
data.append(input.name, input.value);
});
var url = '/ajax/uploadfile';
$.ajax({
url: url,
type: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
processData: false,
cache: false,
data: serializeAndStingifyArray(data),
success: function (result) {
alert('success');
},
error: function () {
alert('error');
}
});
});
function serializeAndStingifyArray(array) {
var o = {};
var a = array;
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return JSON.stringify(o);
};
控制器:
[HttpPost]
public IActionResult UploadFile([FromBody]UploadFileModel model)
{
var result = new JsonResultData();
try
{
if (Request.Form.Files.Count > 0)
{
IFormFile file = Request.Form.Files[0];
//etc
}
}
}
HTML:
<div id="file-list">
<input type="file" name="file" class="file-select" accept="application/pdf,application">
<input type="file" name="file" class="file-select" accept="application/pdf,application" />
</div>
答案 0 :(得分:12)
我从这篇文章开始,它的代码与你的Upload Files In ASP.NET Core 1.0几乎相同(参见Ajax案例)。
这在1.0.0上对我很有用,所以我实现了你的更改,我看到的是它未能在请求中发送文件(客户端问题)。
这是在使用chrome中的F12工作正常时有效负载的样子:(不确定为什么文件内容被chrome隐藏)。
稍微调试一下,您将错误的数据传递给data.append
修复就在这一行
$(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; })
完整代码:
$(document).ready(function () {
$("#submit").click(function (evt) {
var data = new FormData();
i = 0;
$(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; })
var postData = $('#fields :input');
$.each(postData, function (key, input) {
data.append(input.name, input.value);
});
$.ajax({
type: "POST",
url: "/ajax/uploadfile", // <--- Double check this url.
contentType: false,
processData: false,
data: data,
success: function (message) {
alert(message);
},
error: function () {
alert("There was error uploading files!");
}
});
});
});
无需使用[FromBody]
或serializeArray()
[HttpPost]
public IActionResult UploadFilesAjax(MyViewModel xxx )
{
这是我的html,以防万一:
<form method="post" enctype="multipart/form-data">
<div id="file-list">
<input type="file" name="file" class="file-select" accept="application/pdf,application">
<input type="file" name="file" class="file-select" accept="application/pdf,application" />
</div>
<div id="fields">
<input type="text" name="Email" />
</div>
<input type="button"
id="submit"
value="Upload Selected Files" />
</form>