ASP.NET Core 5.0 Razor中如何以数据库获取的自定义名称保存图片
问题原因
空引用报错是以下几个逻辑漏洞导致的:
- 你用
Where(p => p.Id == userId)查询匹配用户后直接遍历,没有做结果校验:如果当前登录用户ID在数据库里没有对应记录,要么整个上传逻辑被直接跳过,要么后续逻辑拿不到用户数据触发异常。 - 匹配到的用户记录中
Uname字段可能为null,你直接对可能为null的对象调用ToString()方法,这是最常见的空引用触发点。 - 没有对入参
postedFiles做空校验:如果用户提交表单时没选任何文件,遍历这个入参的时候也会直接抛空引用错误。
另外你把目录创建、文件名生成的逻辑全放在用户遍历循环里是多余的——按用户主键ID查询理论上最多只会返回1条记录,完全没必要用foreach遍历查询结果。
修复方案
把后端代码替换为如下版本,补全所有空值校验,移除冗余逻辑:
[System.Obsolete] public Microsoft.AspNetCore.Mvc.RedirectToPageResult OnPostUpload(List<IFormFile> postedFiles) { // 校验上传文件有效性 if (postedFiles == null || postedFiles.Count == 0) { Message = "请先选择要上传的图片"; return RedirectToPage("./Index"); } var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); // 直接查询单条匹配的用户记录 var currentUser = Users.FirstOrDefault(p => p.Id == userId); // 校验用户信息有效性 if (currentUser == null || string.IsNullOrWhiteSpace(currentUser.Uname)) { Message = "用户信息异常,请重新登录后再试"; return RedirectToPage("./Index"); } // 目录初始化逻辑移到外层,不用重复判断 string uploadDir = Path.Combine(Environment.WebRootPath, "usersphoto"); if (!Directory.Exists(uploadDir)) { Directory.CreateDirectory(uploadDir); } List<string> uploadedFiles = new List<string>(); // 处理文件名:过滤掉用户名里的非法文件名字符,避免路径报错,不需要多余调用ToString() char[] invalidChars = Path.GetInvalidFileNameChars(); string safeUserName = string.Join("_", currentUser.Uname.Split(invalidChars)); string fileName = $"{safeUserName}.png"; foreach (IFormFile postedFile in postedFiles) { if (postedFile.Length == 0) continue; string savePath = Path.Combine(uploadDir, fileName); using (FileStream stream = new FileStream(savePath, FileMode.Create)) { postedFile.CopyTo(stream); uploadedFiles.Add(fileName); Message += $"<b>{fileName}</b> 上传成功。<br />"; } } return RedirectToPage("./Index"); }
前端代码调整说明
你原来的文件上传标签加的value="aaa"属性是无效的,浏览器出于安全限制不允许给文件上传框预设值,直接删掉这个属性即可,其他前端逻辑不需要改动。
后续建议补充文件格式、大小校验,避免用户上传非图片文件或者超大文件。
内容的提问来源于stack exchange,提问作者Fillo
相关产品推荐
相关产品推荐

