我在用ASP.NET Core 2.2,我使用模型绑定上传文件.

这是我的UserViewModel美元

public class UserViewModel
{
    [Required(ErrorMessage = "Please select a file.")]
    [DataType(DataType.Upload)]
    public IFormFile Photo { get; set; }
}

这是MyView

@model UserViewModel

<form method="post"
      asp-action="UploadPhoto"
      asp-controller="TestFileUpload"
      enctype="multipart/form-data">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

    <input asp-for="Photo" />
    <span asp-validation-for="Photo" class="text-danger"></span>
    <input type="submit" value="Upload"/>
</form>

最后这是MyController

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UploadPhoto(UserViewModel userViewModel)
{
    if (ModelState.IsValid)
    {
        var formFile = userViewModel.Photo;
        if (formFile == null || formFile.Length == 0)
        {
            ModelState.AddModelError("", "Uploaded file is empty or null.");
            return View(viewName: "Index");
        }

        var uploadsRootFolder = Path.Combine(_environment.WebRootPath, "uploads");
        if (!Directory.Exists(uploadsRootFolder))
        {
            Directory.CreateDirectory(uploadsRootFolder);
        }

        var filePath = Path.Combine(uploadsRootFolder, formFile.FileName);
        using (var fileStream = new FileStream(filePath, FileMode.Create))
        {
            await formFile.CopyToAsync(fileStream).ConfigureAwait(false);
        }

        RedirectToAction("Index");
    }
    return View(viewName: "Index");
}

如何将上传的文件限制在5MB以下,并使用特定的扩展名,如.jpeg和.巴布亚新几内亚?我认为这两种验证都是在ViewModel中完成的.但我不知道该怎么做.

推荐答案

您可以自定义验证属性MaxFileSizeAttribute,如下所示

MaxFileSizeAttribute

public class MaxFileSizeAttribute : ValidationAttribute
{
    private readonly int _maxFileSize;
    public MaxFileSizeAttribute(int maxFileSize)
    {
        _maxFileSize = maxFileSize;
    }

    protected override ValidationResult IsValid(
    object value, ValidationContext validationContext)
    {
        var file = value as IFormFile;
        if (file != null)
        {
           if (file.Length > _maxFileSize)
            {
                return new ValidationResult(GetErrorMessage());
            }
        }

        return ValidationResult.Success;
    }

    public string GetErrorMessage()
    {
        return $"Maximum allowed file size is { _maxFileSize} bytes.";
    }
}

AllowedExtensionsAttribute

public class AllowedExtensionsAttribute : ValidationAttribute
{
    private readonly string[] _extensions;
    public AllowedExtensionsAttribute(string[] extensions)
    {
        _extensions = extensions;
    }
    
    protected override ValidationResult IsValid(
    object value, ValidationContext validationContext)
    {
        var file = value as IFormFile;
        if (file != null)
        {
            var extension = Path.GetExtension(file.FileName);
            if (!_extensions.Contains(extension.ToLower()))
            {
                return new ValidationResult(GetErrorMessage());
            }
        }
        
        return ValidationResult.Success;
    }

    public string GetErrorMessage()
    {
        return $"This photo extension is not allowed!";
    }
}

MaxFileSize属性和AllowedExtensions属性添加到Photo属性

public class UserViewModel
{
        [Required(ErrorMessage = "Please select a file.")]
        [DataType(DataType.Upload)]
        [MaxFileSize(5* 1024 * 1024)]
        [AllowedExtensions(new string[] { ".jpg", ".png" })]
        public IFormFile Photo { get; set; }
 }

Asp.net相关问答推荐

*不*使用 asp.net 会员提供程序是个坏主意吗?

在 lambda 表达式中否定 Func

VS2012 中无法识别的标签前缀或设备过滤器asp

EntityFramework 通过 ID 获取对象?

使用 JavaScript 更改 ASP.NET 标签的可见性

从 RowDataBound 事件的 gridview 从单元格中获取值

HttpContext.Current.Request.IsAuthenticated 和 HttpContext.Current.User.Identity.IsAuthenticated 有什么区别?

UseSqlServer 方法缺少 MVC 6

asp.net Button OnClick 事件未触发

ASP.NET 中的 <%# Bind("") %> 和 <%# Eval("") %> 有什么区别?

ASP.NET 中的多选下拉列表

使用 LINQ 进行递归控制搜索

解析器错误:无法创建类型

如何防止 XXE 攻击(.NET 中的 XmlDocument)

.NET 4.0 中的自定义 MembershipProvider

如何获取程序集的最后修改日期?

ASP.NET 身份,需要强密码

解析器错误:此处不允许使用_Default,因为它没有扩展类System.Web.UI.Page和 MasterType 声明

Ashx 文件中的 HttpContext.Current.Session 为空

如何使用 int ID 列更改 ASP.net Identity 2.0 的表名?