ASP.NET MVC 用户 ID Link 与其他表

ASP.NET MVC User ID Link with other Tables

我正在研究用于存储用户财务数据的数据输入系统。每个用户将在 table 中分别输入他的收入和支出。 table 设计如下:

这是我的模型示例:

public class Revenue
{
    [Key]
    public int RevenueId { get; set; }
    public int Year { get; set; }
    public double Source1 { get; set; } = 0;
    public double Source2 { get; set; } = 0;
    public double Source3 { get; set; } = 0;
    public double Source4 { get; set; } = 0;

    // Foreign Key Relationship
    public string OrganizationId{ get; set; }
    public virtual Organization Organization{ get; set; }
}

public class Organization
{
    public virtual ICollection<Revenue> Revenues { get; set; }
    public virtual ICollection<Expense> Expenses { get; set; }
}

这是 DBContext:

public class AppDbContext : IdentityDbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    // Create tables in DB
    public DbSet<Organization > Organization { get; set; }
    public DbSet<Revenue> Revenue { get; set; }
    public DbSet<Expense> Expense { get; set; }
}

这是控制器中的创建操作:

    // GET: Revenue/Create
    public IActionResult Create()
    {
        return View();
    }

    // POST: Revenue/Create
    // To protect from overposting attacks, enable the specific properties you want to bind to.
    // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("RevenueId,Year,Source1,Source2,...,OrganizationId")] Revenue revenue)
    {
        if (ModelState.IsValid)
        {
            _context.Add(revenue);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        ViewData["OrganizationId"] = new SelectList(_context.OrganizationId, "Id", "Id", revenue.OrganizationId);
        return View(revenue);
    }

最后,创建视图:

@using Microsoft.AspNetCore.Identity

@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
    @{
        ViewData["Title"] = "Create";
    }
    
    <h1>Create</h1>
    
    <h4>Revenue</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Create">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="Year" class="control-label"></label>
                    <input asp-for="Year" class="form-control" />
                    <span asp-validation-for="Year" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Source1" class="control-label"></label>
                    <input asp-for="Source1" class="form-control" />
                    <span asp-validation-for="Source1" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Source2" class="control-label"></label>
                    <input asp-for="Source2" class="form-control" />
                    <span asp-validation-for="Source2" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Source3" class="control-label"></label>
                    <input asp-for="Source3" class="form-control" />
                    <span asp-validation-for="Source3" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Source4" class="control-label"></label>
                    <input asp-for="Source4" class="form-control" />
                    <span asp-validation-for="Source4" class="text-danger"></span>
                </div>
            <div class="form-group">
                <label asp-for="OrganizationId" class="control-label"></label>
                <input asp-for="OrganizationId" class="form-control" value="@UserManager.GetUserId(User)"/>
                <span asp-validation-for="OrganizationId" class="text-danger"></span>
            </div>
                </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");}
    }

因此,经过大量搜索后,我能够使用 UserManager 捕获用户 ID 并将其分配给隐藏字段,然后将其与表单一起发送。但是,这没有用,表单没有提交,也没有显示任何错误消息。

这是将用户 ID 捕获为外键的正确方法吗?如何修复创建操作?

您并没有具体说明您的身份验证。如果您使用典型的 ASP.Net 身份验证,您可以使用 User.Identity.Name,如下所示:

        if (ModelState.IsValid)
        {
            revenue.UserId = User.Identity.Name
            _context.Add(revenue);
            ...

从 .NET 6 开始,为了将模型中的属性分配为 Nullable ?应在属性名后加,否则必填

问题是传递了 UserId 但 User 对象为空(应该是因为它只是一个引用)。

所以模型应该是:

public class Revenue
{
    [Key]
    public int RevenueId { get; set; }
    public int Year { get; set; }
    public double Source1 { get; set; } = 0;
    public double Source2 { get; set; } = 0;
    public double Source3 { get; set; } = 0;
    public double Source4 { get; set; } = 0;

    // Foreign Key Relationship
    public string OrganizationId{ get; set; }
    public Organization? Organization{ get; set; }
}

通过在我们从 UserManager 获得的隐藏字段中传递用户 ID,视图将保持原样。