asp.net-mvc 在 ASP.NET MVC 中验证失败后如何保持输入类型=文件字段值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/967916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:38:24  来源:igfitidea点击:

How to keep input type=file field value after failed validation in ASP.NET MVC?

asp.net-mvcforms

提问by Chaddeus

I've got a simple form in an MVC app I've made. It contains a file field so users can upload an image. It all works great.

我在我制作的 MVC 应用程序中有一个简单的表单。它包含一个文件字段,以便用户可以上传图像。这一切都很好。

Problem is, if the form submit fails validation the content of the file field is lost (other fields remain populated, thx HtmlHelpers!). How do I keep the file field populated after a failed validation?

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

TIA!

蒂亚!

采纳答案by Alexander Prokofyev

Browsers are designed in such way because of security risks. It's impossible to set value of file input box in HTML source or by Javascript. Otherwise malicious script could steal some private file without user attention.

由于安全风险,浏览器以这种方式设计。无法在 HTML 源代码或 Javascript 中设置文件输入框的值。否则恶意脚本可能会在用户不注意的情况下窃取一些私人文件。

There is an interesting informationabout the subject.

一个关于这个主题的有趣信息

回答by Michael

As far as I know you cannot set the value of a HTML file input box. I would suggest coupling the file input box with a label or text box.

据我所知,您无法设置 HTML 文件输入框的值。我建议将文件输入框与标签或文本框结合起来。

Then you can populate the it with the value from the file input box to be resubmitted later.

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

回答by AGuyCalledGerald

I would recommend doing the validation beforehand via ajax and do a partial page update. In this case, you will not lose the file.

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

回答by gokkor

There are flash based file uploaders. Try one of them. Some of them even falls back to regular file input box if flash and java script is not supported. I advise to look for jQuery plugins.

有基于 Flash 的文件上传器。尝试其中之一。如果不支持 flash 和 java 脚本,其中一些甚至回退到常规文件输入框。我建议寻找 jQuery 插件。

回答by Patrick Cornelissen

If the file isn't too big you could base64 it and use this as value for a hidden field.

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

回答by Agi Hammerthief

You cannot set the value of a HTML file input box. As a workaround, replace the file upload box with a hidden input field when outputting the form after validation.

您不能设置 HTML 文件输入框的值。作为一种解决方法,在验证后输出表单时,将文件上传框替换为隐藏的输入字段。

On submission, you populate the hidden field with the value from the file input box (to be resubmitted later). Remember to have either the file upload or hidden field name present at any one time (not both):

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

Note:The code below is for illustration/explanationpurposes only. Replace it with the code appropriate to the language you use.

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

<?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 } ?>

回答by Arfath

I fail to agree with "impossible" being marked as correct answer. In case anybody is still in search of a possibility, here is the work around that worked for me. I'm using MVC5. The idea is to use a session variable. I got the idea from ASP.Net Form.

我不同意将“不可能”标记为正确答案。如果有人仍在寻找可能性,这里是对我有用的解决方法。我正在使用 MVC5。这个想法是使用会话变量。我从ASP.Net Form得到了这个想法。

My Model/ViewModel (only relevant properties):

我的模型/视图模型(仅相关属性):

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

        public HttpPostedFileBase uploadFile { get; set; }
    }

In my controller (HttpPost): //Check

在我的控制器(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...
}

Finally within my edit view: here, i am conditionally showing the file upload control.

最后在我的编辑视图中:在这里,我有条件地显示文件上传控件。

< 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>
}