如何在 MVC 5 中以单个 Ajax POST 请求发送 ViewModel 和文件?
Posted
技术标签:
【中文标题】如何在 MVC 5 中以单个 Ajax POST 请求发送 ViewModel 和文件?【英文标题】:How to send ViewModel and a file in single Ajax POST request, in MVC 5? 【发布时间】:2015-12-24 11:36:35 【问题描述】:我有一个 ASP.NET MVC 5 应用程序。我正在尝试使用模型数据发送 POST 请求,并且还包括用户选择的文件。 这是我的 ViewModel(为清楚起见进行了简化):
public class Model
public string Text get; set;
public long Id get; set;
这是控制器动作:
[HttpPost]
public ActionResult UploadFile(long userId, Model model)
foreach (string file in Request.Files)
// process files
return View("Index");
html 输入元素:
<div>
<input type="file" name="UploadFile" id="txtUploadFile" />
</div>
还有 javascript 代码:
$('#txtUploadFile').on('change', function (e)
var data = new FormData();
for (var x = 0; x < files.length; x++)
data.append("file" + x, files[x]);
data.append("userId", 1);
data.append("model", JSON.stringify( Text: 'test text', Id: 3 ));
$.ajax(
type: "POST",
url: '/Home/UploadFile',
contentType: false,
processData: false,
data: data,
success: function (result) ,
error: function (xhr, status, p3, p4)
);
);
问题是,当请求到达控制器操作时,我填充了文件和“userId”,但“模型”参数始终为空。填充 FormData 对象时我做错了吗?
【问题讨论】:
使用 contentType: "application/json" 它不会发送文件。 参考this answer - 而不是data.append("model", JSON.stringify( Text: 'test text', Id: 3 ));
它应该是data.append(Text, 'test text'); data.append(Id, 3);
谢谢,现在我知道 FormData 有什么问题了!
【参考方案1】:
这是我使用 MVC5 和 IE11 / chrome 测试的内容
查看
<script>
$(function ()
$("#form1").submit(function ()
/*You can also inject values to suitable named hidden fields*/
/*You can also inject the whole hidden filed to form dynamically*/
$('#name2').val(Date);
var formData = new FormData($(this)[0]);
$.ajax(
url: $(this).attr('action'),
type: $(this).attr('method'),
data: formData,
async: false,
success: function (data)
alert(data)
,
error: function()
alert('error');
,
cache: false,
contentType: false,
processData: false
);
return false;
);
);
</script>
<form id="form1" action="/Home/Index" method="post" enctype="multipart/form-data">
<input type="text" id="name1" name="name1" value="value1" />
<input type="hidden" id ="name2" name="name2" value="" />
<input name="file1" type="file" />
<input type="submit" value="Sublit" />
</form>
控制器
public class HomeController : Controller
[HttpGet]
public ActionResult Index()
return View();
[HttpPost]
public ActionResult Index(HttpPostedFileBase file1, string name1, string name2)
var result = new List<string>();
if (file1 != null)
result.Add(string.Format("0: 1 bytes", file1.FileName, file1.ContentLength));
else
result.Add("No file");
result.Add(string.Format("name1: 0", name1));
result.Add(string.Format("name2: 0", name2));
return Content(string.Join(" - ", result.ToArray()));
感谢 Silver89 的answer
【讨论】:
问题是我的表单上没有所有必填字段,所以Model是用JS代码构造的,就在发送POST请求之前。 @IgorGoroshko 我认为有很多方法可以解决这个问题,您可以测试的一种方法是将您的值注入到合适的命名隐藏字段中。 @IgorGoroshko 更新为在隐藏字段中注入值。 谢谢,这可行,但我的代码中的问题是我们有一个 JS 函数,它接受 Model 作为参数。该函数负责在 input:file 元素组中查找文件并将它们与模型一起发送,因此我们无法访问表单元素。 @IgorGoroshko 正如我所说,有很多方法可以做到这一点,例如,data = new FormData(); data.append( 'file', $( '#file' )[0].files[0] );
以上是关于如何在 MVC 5 中以单个 Ajax POST 请求发送 ViewModel 和文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET MVC 中以 JSON 格式返回 500 错误?
MVC中前台如何向后台传递数据------$.get(),$post(),$ajax(),$.getJSON()总结
如何将两个数组作为 POST 请求参数从 AJAX 发送到 MVC 控制器(ASP .NET Core 3.1 剃须刀)?