如何在ASP.NET MVCvalidation失败后保持inputtypes=文件字段值?

我已经在一个MVC应用程序中获得了一个简单的表单。 它包含一个文件字段,用户可以上传图像。 这一切都很好。

问题是,如果表单提交失败validation文件字段的内容丢失(其他字段仍然填充,thtml HtmlHelpers!)。 validation失败后,如何保持文件字段填充?

TIA!

浏览器是以这种方式devise的,因为存在安全风险。 在HTML源代码或Javascript中设置文件input框的值是不可能的。 否则恶意脚本可能会窃取一些私人文件,而无需用户关注。

有一个有关这个问题的有趣的信息 。

据我所知,你不能设置一个HTML文件input框的值。 我会build议耦合文件input框与标签或文本框。

然后,您可以使用文件input框中的值填充它,稍后再重新提交。

有基于Flash的file upload。 尝试其中之一。 如果不支持flash和java脚本,其中一些甚至会回退到常规文件input框。 我build议寻找jQuery插件。

如果文件不是太大,你可以base64它,并将其用作隐藏字段的值。

您不能设置HTML文件input框的值。 作为解决方法,在validation后输出表单时,将文件上载框replace为隐藏的input字段。

提交时,使用文件input框中的值填充隐藏字段(稍后重新提交)。 请记住在任何时候都有file upload或隐藏字段名称(不能同时存在):

注意:下面的代码仅用于说明/解释目的。 将其replace为适合您所用语言的代码。

<?php /* You may need to sanitize the value of $_POST['file_upload']; * this is just a start */ if(isset($_POST['file_upload']) && !empty($_POST['file_upload'])){ ?> <input type="hidden" name="file_upload" value="<?php print($_POST['file_upload']); ?>" /> <?php } else { ?> <input type="file" name="file_upload" /> <?php } ?> 

我build议通过ajax事先进行validation,并进行部分页面更新。 在这种情况下,您不会丢失文件。

我不同意“不可能”被标记为正确的答案。 如果有人还在寻找可能性,那么这是为我工作的工作。 我正在使用MVC5。 这个想法是使用会话variables。 我从ASP.Net窗体中获得了这个想法。

我的模型/ ViewModel(只有相关的属性):

 public partial class emp_leaves { public string fileNameOrig { get; set; } public byte[] fileContent { get; set; } public HttpPostedFileBase uploadFile { get; set; } } 

在我的控制器(HttpPost)://检查

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(emp_leaves emp_leaves) { if (emp_leaves.uploadFile != null && emp_leaves.uploadFile.ContentLength>0 && !string.IsNullOrEmpty(emp_leaves.uploadFile.FileName)) { emp_leaves.fileNameOrig = Path.GetFileName(emp_leaves.uploadFile.FileName); emp_leaves.fileContent = new byte[emp_leaves.uploadFile.ContentLength]; emp_leaves.uploadFile.InputStream.Read(emp_leaves.fileContent, 0, emp_leaves.uploadFile.ContentLength); Session["emp_leaves.uploadFile"] = emp_leaves.uploadFile; //saving the file in session variable here } else if (Session["emp_leaves.uploadFile"] != null) {//if re-submitting after a failed validation you will reach here. emp_leaves.uploadFile = (HttpPostedFileBase)Session["emp_leaves.uploadFile"]; if (emp_leaves.uploadFile != null && emp_leaves.uploadFile.ContentLength>0 && !string.IsNullOrEmpty(emp_leaves.uploadFile.FileName)) { emp_leaves.fileNameOrig = Path.GetFileName(emp_leaves.uploadFile.FileName); emp_leaves.uploadFile.InputStream.Position = 0; emp_leaves.fileContent = new byte[emp_leaves.uploadFile.ContentLength]; emp_leaves.uploadFile.InputStream.Read(emp_leaves.fileContent, 0, emp_leaves.uploadFile.ContentLength); } } //code to save follows here... } 

最后在我的编辑视图:在这里,我有条件地显示file upload控制。

 < script type = "text/javascript" > $("#removefile").on("click", function(e) { if (!confirm('Delete File?')) { e.preventDefault(); return false; } $('#fileNameOrig').val(''); //toggle visibility for concerned div $('#downloadlrfdiv').hide(); $('#uploadlrfdiv').show(); return false; }); < /script> 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> @model PPMSWEB.Models.emp_leaves @{ HttpPostedFileBase uploadFileSession = Session["emp_leaves.uploadFile"] == null ? null : (HttpPostedFileBase)Session["emp_leaves.uploadFile"]; } @using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.AntiForgeryToken() <div class="row"> @*irrelevant content removed*@ <div id="downloadlrfdiv" @((!String.IsNullOrEmpty(Model.fileNameOrig) && (Model.uploadFile==n ull || uploadFileSession !=null)) ? "" : "style=display:none;")> <label>Attachment</label> <span> <strong> <a id="downloadlrf" href="@(uploadFileSession != null? "" : Url.Action("DownloadLRF", "emp_leaves", new { empLeaveId = Model.ID }))" class="text-primary ui-button-text-icon-primary" title="Download attached file"> @Model.fileNameOrig </a> </strong> @if (isEditable && !Model.readonlyMode) { @Html.Raw("&nbsp"); <a id="removefile" class="btn text-danger lead"> <strong title="Delete File" class="glyphicon glyphicon-minus-sign"> </strong> </a> } </span> </div> <div id="uploadlrfdiv" @(!(!String.IsNullOrEmpty(Model.fileNameOrig) && Model.uploadFile==n ull) && !Model.readonlyMode ? "" : "style=display:none;")> <label>Upload File</label> @Html.TextBoxFor(model => model.uploadFile, new { @type = "file", @class = "btn btn-default", @title = "Upload file (max 300 KB)" }) @Html.ValidationMessageFor(x => x.uploadFile) </div> </div> }