MVC中ModelState不识别已注册合法文件上传扩展名问题
问题:上传合法图片文件时ModelState验证失败
我创建了一个联系表单,相关代码如下:
视图代码
@model LessonsLearned.Domain.Common.ViewModels.ContactFormViewModel @using (Html.BeginForm("SubmitForm", "Help", FormMethod.Post, new { enctype = "multipart/form-data" })) { <p>@LLResources.GetResourceText("Question")</p> <br /> <div class="row form-group"> <div class="col-12"> <b>@LLResources.GetResourceText("Admin_Email")</b> </div> <div class="col-12"> @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control", autocomplete = "off" } }) </div> </div> <div class="row form-group"> <div class="col-12"> <b>@LLResources.GetResourceText("General_Name")</b> </div> <div class="col-12"> @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control", autocomplete = "off" } }) </div> </div> <div class="row form-group"> <div class="col-12"> <b>@LLResources.GetResourceText("Admin_SchoolName")</b> </div> <div class="col-12"> @Html.EditorFor(model => model.SchoolName, new { htmlAttributes = new { @class = "form-control", autocomplete = "off" } }) </div> </div> <div class="row form-group"> <div class="col-12"> <b>@LLResources.GetResourceText("Message")</b> </div> <div class="col-12"> @Html.EditorFor(model => model.Message, new { htmlAttributes = new { @class = "form-control", autocomplete = "off" } }) </div> </div> <div class="row form-group"> <div class="col-12"> <b>@LLResources.GetResourceText("Observation_Attachments")</b> </div> <div class="col-12"> @Html.TextBoxFor(m => m.File, new { type = "file" }) @Html.ValidationMessageFor(m => m.File) </div> </div> <div class="row"> <div class="col-12"> <input type="submit" value="Submit" class="btn btn-success float-md-right mr-md-2" /> </div> </div> }
视图模型代码
public class ContactFormViewModel { [Required(ErrorMessage = "Email address is required.")] [EmailAddress(ErrorMessage = "Must be a valid email address.")] public string Email { get; set; } [Required(ErrorMessage = "Name is required.")] public string Name { get; set; } [Required(ErrorMessage = "School name is required.")] public string SchoolName { get; set; } [Required(ErrorMessage = "Message is required.")] [DataType(DataType.MultilineText)] public string Message { get; set; } [FileExtensions(Extensions = "jpg, jpeg, png")] public HttpPostedFileBase File { get; set; } }
控制器提交方法
[HttpPost] public ActionResult SubmitForm(ContactFormViewModel contactFormViewModel) { if (ModelState.IsValid) { //Do stuff ViewBag.result = "Form submitted successfully!"; return View("Index", new ContactFormViewModel()); } else { //Don't do stuff ViewBag.result = "Form was not submitted, please fix errors."; return View("Index", contactFormViewModel); } return RedirectToAction("Index"); }
但当上传jpg或png格式的文件并提交表单时,ModelState始终提示错误:The File field only accepts files with the following extensions: .jpg, .jpeg, .png,确认上传的确实是jpg或png文件,请问为何无法识别?
解决方案
问题出在[FileExtensions]特性的使用细节上:
- 扩展名列表格式错误:
FileExtensions特性要求扩展名之间不能有空格,你当前的写法是"jpg, jpeg, png",逗号后的空格会让验证逻辑把jpeg(带空格)和png(带空格)判定为合法扩展名,但实际上传文件的扩展名是不带空格的,因此验证失败。
修改视图模型中的特性,去掉扩展名之间的空格即可:
[FileExtensions(Extensions = "jpg,jpeg,png")] public HttpPostedFileBase File { get; set; }
额外补充:FileExtensions特性仅检查文件名后缀,不会验证文件实际内容。如果需要确保上传的是真实图片,可在控制器中添加MIME类型验证:
if (contactFormViewModel.File != null) { var allowedMimeTypes = new[] { "image/jpeg", "image/png" }; if (!allowedMimeTypes.Contains(contactFormViewModel.File.ContentType)) { ModelState.AddModelError("File", "Only JPG/PNG images are allowed."); } }
内容的提问来源于stack exchange,提问作者Hannah Hayes
相关产品推荐
相关产品推荐

