简体   繁体   English

ASP.NET MVC 用户 ID 与其他表的链接

[英]ASP.NET MVC User ID Link with other Tables

I am working on a Data Entry system for storing users financial data.我正在研究用于存储用户财务数据的数据输入系统。 Each user will enter his Revenues and Expenses each in a table.每个用户将在表格中分别输入他的收入和费用。 The tables were designed as follows:表格设计如下:

  • Primary Key: Rev/Exp ID主键:Rev/Exp ID
  • Foreign Key: Organization ID外键:组织 ID

This is a sample for my models:这是我的模型的示例:

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; }
}

This is the DBContext:这是 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; }
}

Here is the Create Action in the Controller:这是 Controller 中的创建操作:

    // 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);
    }

Finally, Create View:最后,创建视图:

@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");}
    }

So, after a lot of search I was able to capture user ID with UserManager and assigning it to a hidden field, then sending it with the form.因此,经过大量搜索后,我能够使用 UserManager 捕获用户 ID 并将其分配给隐藏字段,然后将其与表单一起发送。 However, that did not work, the form is not submitting and no error messages are displayed neither.但是,这不起作用,表单没有提交,也没有显示任何错误消息。

Is this is a correct way of capturing user ID as a Foreign Key and how to fix the Create Action?这是将用户 ID 捕获为外键的正确方法以及如何修复创建操作?

You didn't really specify anything about your authentication.您并没有真正指定有关您的身份验证的任何内容。 If you are using typical ASP.Net authentication, you can probably use User.Identity.Name, like this:如果您使用典型的 ASP.Net 身份验证,您可能可以使用 User.Identity.Name,如下所示:

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

As from .NET 6, in order to assign an attribute in a model to be Nullable the?从 .NET 6 开始,为了在一个 model 中分配一个属性为 Nullable 吗? should be added after the name of the attribute, otherwise it is required.应在属性名称后添加,否则为必填项。

The problem was that the UserId is passed but the User object is null (which should be because it is just a reference).问题是传递了 UserId 但 User object 是 null (这应该是因为它只是一个参考)。

So the model should be:所以 model 应该是:

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; }
}

And the view will be as is by passing user ID in a hidden field that we got from UserManager.通过在我们从 UserManager 获得的隐藏字段中传递用户 ID,视图将保持原样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM