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

如何在填写表单时将当前Identity用户设置为模型属性?

解决EF中传递当前用户到Reports模型的问题

你现在遇到的核心问题是:试图从视图传递用户对象到控制器,但模型绑定无法直接把字符串(用户名/ID)转换成IdentityUser实体,而且这种方式还存在安全风险。下面给你两种靠谱的解决方案,优先推荐第一种:

1. 优化模型结构,控制器直接获取当前用户(推荐)

首先,给你的Reports模型添加外键属性,这是EF处理导航属性的标准做法,能避免很多映射问题:

public class Reports 
{ 
    [Key] 
    public int ReportId { get; set; } 
    public string Name { get; set; }
    
    // 添加用户外键(必须和IdentityUser的主键类型一致,默认是string)
    public string UserId { get; set; }
    
    // 配置外键与导航属性的关联
    [ForeignKey(nameof(UserId))]
    public IdentityUser User { get; set; }
}

接下来,修改视图,不需要传递任何用户相关的隐藏字段——因为控制器可以直接从请求上下文获取当前登录用户,既安全又简单:

@model Reports 
@using Microsoft.AspNetCore.Identity 
@inject UserManager<IdentityUser> UserManager 
<body> 
<div class="container1"> 
<form asp-action="Submit" method="post" role="form"> 
<div class="form-group row"> 
<label asp-for="Name" class="col-md-2 control-label"></label> 
<div class="col-md-5"> 
<input asp-for="Name" class="form-control" /> 
</div> 
</div>

<!-- 移除原来的User隐藏字段,不需要从视图传用户信息 -->
<div class="form-group row"> 
<div class="col-md-offset-2 col-md-5"> 
<input type="submit" class="btn btn-primary" value="Next" /> 
</div> 
</div>
</form>
</div>
</body>

最后,在控制器的Submit方法里,通过UserManager获取当前用户,给模型赋值后保存:

public class ReportsController : Controller
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly YourDbContext _dbContext; // 替换成你的DbContext类名

    // 构造函数注入依赖
    public ReportsController(UserManager<IdentityUser> userManager, YourDbContext dbContext)
    {
        _userManager = userManager;
        _dbContext = dbContext;
    }

    [HttpPost]
    public async Task<IActionResult> Submit(Reports model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // 获取当前登录用户的ID(最直接的方式)
        var currentUserId = _userManager.GetUserId(User);
        model.UserId = currentUserId;

        // 如果你需要完整的IdentityUser对象,也可以这样获取:
        // var currentUser = await _userManager.GetUserAsync(User);
        // model.User = currentUser;

        _dbContext.Reports.Add(model);
        await _dbContext.SaveChangesAsync();

        return RedirectToAction("Index"); // 替换成你要跳转的页面
    }
}

2. 如果坚持从视图传用户ID(不推荐)

如果你一定要从视图传递用户ID,那可以修改视图里的隐藏字段,传递用户ID而非用户名:

<input asp-for="UserId" type="hidden" value="@UserManager.GetUserId(User)" />

然后控制器里直接接收model.UserId,和上面的控制器逻辑一样。但这种方式不如控制器直接获取安全——因为隐藏字段可以被恶意篡改,而从HttpContext获取的用户信息是经过身份验证的,无法伪造。

为什么你原来的方式不行?

你原来的代码里@UserManager.GetUserName()缺少参数,正确写法是@UserManager.GetUserName(User),但就算传对了用户名,模型绑定也不会自动去数据库查询对应的IdentityUser实体并赋值给model.User——EF需要的是实体引用或外键值,不是字符串形式的用户名/ID。

内容的提问来源于stack exchange,提问作者Fintan Roche

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:47:26