Joe*_*Min 1 asp.net ajax asp.net-mvc jquery asynchronous
这是场景:
我有一个使用ASP.NET MVC开发的网站,该网站中有一个表单,其中包含多个输入字段,其中包括几个文件上传字段。
我正在尝试做的是,一旦用户选择了文件,就将文件 异步上传,以便在文件上传时,用户可以继续填写其他输入。
服务器接收 并 验证文件有效后,当用户单击“提交”按钮时,表单将与上载的文件一起发送并保存。
我假设我需要有一个单独的控制器操作来处理异步上传,但是那我将如何从一个处理表单提交的不同操作(在同一控制器内)访问这些上传文件呢?
如果我需要在提交表单之前临时存储文件,那么理想的存储位置在哪里?
小智 5
如果您在选择表单时已经上传了文件,那么在提交表单时上传文件似乎毫无意义(您可能希望enctype从表单元素中删除该属性。
基本步骤是当用户使用ajax选择文件时使用(上载)上载文件FormData,保存文件并返回该文件的路径,以便最终提交表单时也可以发布该信息。
首先定义视图模型以表示要在视图中显示/编辑的内容
public class FileAttachmentVM
{
public string Path { get; set; }
public string DisplayName { get; set; }
}
public class MyViewModel
{
.... // properties to display/edit in the view
public List<FileAttachmentVM> Files { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并认为
@model MyViewModel
...
@using (Html.BeginForm())
{
....
<div id="file-inputs"></div> // placeholder for the file collection hidden inputs
}
<div id="file-names"></div> // place holder for the collection of file already uploaded
<input type="file" id="file" />
<button type="button" id="upload">Upload</button>
// template for adding new inputs for the file collection
<div id="template" style="display:none">
<div class="file-details">
<input type="hidden" class="file-path" name="Files[#].Path" value="" />
<input type="hidden" class="file-name" name="Files[#].DisplayName" value="" />
<input type="text" name="Files.Index" value="#" />
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
以及用于上传文件和更新DOM的脚本
var fileInputs = $('#file-inputs');
var fileNames = $('#file-names');
$('#Upload').click(function () {
var file = $('#file').get(0).files[0];
if (!file) {
return;
}
var formData = new FormData();
formData.append("file", file);
$.ajax({
url: '@Url.Action("Upload", "...")',// add controller name
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (data) {
if (!data) {
// Oops, something went wrong
return;
}
$('#file').val(''); // clear file input
// Add the display name
fileNames.append($('<div></div>').text(data.DisplayName));
// Add the inputs
var index = (new Date()).getTime(); // unique indexer
var clone = $('#template').clone(); // clone the template
clone.html($(clone).html().replace(/#/g, index)); // update the indexer
fileInputs.append(clone.html()); // append the inputs
// update the input values
var lastFile = fileInputs.find('.file-details').last();
lastFile.find('.file-path').last().val(data.Path);
lastFile.find('.file-name').last().val(data.DisplayName);
}
});
});
Run Code Online (Sandbox Code Playgroud)
最后是控制器方法
[HttpPost]
public JsonResult Upload(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var displayName = Path.GetFileName(file.FileName);
var fileExtension = Path.GetExtension(displayName);
var fileName = string.Format("{0}{1}", Guid.NewGuid(), fileExtension);
var path = Path.Combine(Server.MapPath("~/App_Data/Files"), fileName);
file.SaveAs(path);
return Json(new { DisplayName = displayName, Path = path });
}
return Json(null);
}
Run Code Online (Sandbox Code Playgroud)
然后在控制器方法中将表单提交到
public ActionResult Create(MyViewModel model)
{
// Initialize a data model, map the view model properties to it and save
// Loop through model.Files and save each file display name and path to the database (along with the ID of the entity you created/updated
Run Code Online (Sandbox Code Playgroud)
有关代码的一些注释。
.change()
事件而不是按钮.click()事件。Guid用来保存,以确保它们是唯一的,并且如果另一个用户上传具有相同名称的文件,则不会存在文件被覆盖的风险。| 归档时间: |
|
| 查看次数: |
3938 次 |
| 最近记录: |