You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:35:28