【问题标题】:Why does ModelState.IsValid always return false when trying to upload an image in ASP.NET?为什么尝试在 ASP.NET 中上传图像时 ModelState.IsValid 总是返回 false?
【发布时间】:2022-12-18 16:54:17
【问题描述】:

我一直尝试在 asp.net core 中上传图片,但无论我怎么做,我都会遇到同样的问题。 ModelState.IsValid 返回错误。我最终屈服了,只是复制并粘贴了别人的作品,希望如果我能让它发挥作用,即使它是别人的,我也能明白我哪里出错了。即使使用我的脚本小子技术,我的计划也被挫败了。所以现在我遇到了比以往任何时候都更聪明的人。

这是我复制的教程from

我的模型看起来像这样:

using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

public class ImageModel
{
    [Key]
    public int ImageId { get; set; }

    [Column(TypeName = "nvarchar(50)")]
    public string Title { get; set; }

    [Column(TypeName = "nvarchar(100)")]
    [DisplayName("Image Name")]
    public string ImageName { get; set; }

    [NotMapped]
    [DisplayName("Upload File")]
    public IFormFile ImageFile { get; set; }
}

我的控制器的相关部分

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageFile")] ImageModel imageModel)
{
    var errors = ModelState.Values.SelectMany(v => v.Errors);

    if (ModelState.IsValid)
    {
        // Save image to wwwroot/image
        string wwwRootPath = _hostEnvironment.WebRootPath;
        string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
        string extension = Path.GetExtension(imageModel.ImageFile.FileName);
        imageModel.ImageName = fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
        string path = Path.Combine(wwwRootPath + "/Image/", fileName);

        using (var fileStream = new FileStream(path, FileMode.Create))
        {
            await imageModel.ImageFile.CopyToAsync(fileStream);
        }

        // Insert record
        _context.Add(imageModel);
        await _context.SaveChangesAsync();

        return RedirectToAction(nameof(Index));
    }

    return View(imageModel);
}

最后是视图

@model ImageModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>ImageModel</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create" enctype="multipart/form-data">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ImageFile" class="control-label"></label>
                <input asp-for="ImageFile" accept="image/*" />
                <span asp-validation-for="ImageFile" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

我看了一下这个question 并听从了建议。它返回的错误是

ModelError、ModelError.Exception、ModelError.ErrorMessage Microsoft.AspNetCore.Mvc.ModelBinding.ModelError
图片名称字段是必需的

感谢您的时间

【问题讨论】:

  • 也许如果您将 [Bind("ImageId,Title,ImageFile")] 替换为 [FromForm]

标签: c# asp.net-core-mvc


【解决方案1】:

ModelState 不查看 [Bind] 中的属性,而是查看模型的所有属性。

创建一个没有ImageName属性的新视图模型或设置ImageName默认值

public class ImagePostModel
{
    [Key]
    public int ImageId { get; set; }

    [Column(TypeName = "nvarchar(50)")]
    public string Title { get; set; }

    //[Column(TypeName = "nvarchar(100)")]
    //[DisplayName("Image Name")]
    //public string ImageName { get; set; } = String.Empty Alternative solution

    [NotMapped]
    [DisplayName("Upload File")]
    public IFormFile ImageFile { get; set; }
}

【讨论】:

    【解决方案2】:

    有多种解决方案

    解决方案1: 在你的 startup/program.cs 中设置如下:

    builder.Services.AddControllersWithViews(options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);
    

    更多详情,可以查看document

    解决方案2:

    在您不想验证的属性上添加 [ValidateNever] 属性

    解决方案3:

    创建一个 ViewModel 不包含视图的 ImageName 属性

    【讨论】:

      猜你喜欢
      • 2013-02-26
      • 1970-01-01
      • 2012-11-02
      • 2018-02-16
      • 2011-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      相关资源
      最近更新 更多