【问题标题】:Extend ASP.Net Identity with navigation property使用导航属性扩展 ASP.Net Identity
【发布时间】:2013-12-13 11:44:35
【问题描述】:

最近刚开始在 VS2013 中使用 ASP.Net Identity。我启动了一个 MVC5 项目,并为它使用了默认模板,带有个人帐户。我正在尝试使用以下字段扩展从 IdentityUser 继承的 ApplicationUser 类:

//this is my code first entity
public class ApplicationUser : IdentityUser
{
    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public virtual SellingLocation Location { get; set; }
}

我已经用 Name 和 EmailAddress 的文本框扩展了 Register.cshtml,更新了 registerviewmodel 并添加了一个包含所有 SellingLocation 的列表来填充下拉列表。

public class RegisterViewModel
{
    [Required]
    [Display(Name = "Användarnamn")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Lösenord")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Bekräfta lösenord")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    [Required]
    [Display(Name = "Säljarens namn")]
    public string Name { get; set; }

    [Required]
    [Display(Name = "Epostadress")]
    public string EmailAddress { get; set; }

    [Display(Name = "Försäljningställe")]
    public int SellingLocationId { get; set; }

    public List<SellingLocationViewModel> SellingLocations { get; set; }
}

以及下拉菜单的Register.cshtml代码:

<div class="form-group">
    @Html.LabelFor(m => m.SellingLocationId, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.DropDownListFor(m => m.SellingLocationId, new SelectList(Model.SellingLocations, "Id", "Name"))
    </div>
</div>

问题出在帐户控制器中。当我尝试添加此新用户时,会创建 SellingLocation 的新副本(数据库中的新行),而不是仅向下拉列表中所选值指向的行添加引用(外键)。我做错了什么?

// GET: /Account/Register
    [AllowAnonymous]
    public ActionResult Register()
    {
        var regvm = new RegisterViewModel();
        regvm.SellingLocations = GetSellingLocations();
        return View(regvm);
    }
    private List<SellingLocationViewModel> GetSellingLocations()
    {
        return Mapper.Map<List<SellingLocation>, List<SellingLocationViewModel>>(db.SellingLocations.ToList());
    }

        //
    // POST: /Account/Register
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            //get the SellingLocation from the id from the selected value in dropdown
            var sellingloc = db.SellingLocations.Find(model.SellingLocationId);
            //creating user object, adding new data
            var user = new ApplicationUser() { UserName = model.UserName, Name = model.Name, EmailAddress = model.EmailAddress, Location = sellingloc };
            var result = await UserManager.CreateAsync(user, model.Password);
            //this will create a new row in SellingLocations, not just add a reference in AspNetUsers to the old row as expected.
            if (result.Succeeded)
            {
                await SignInAsync(user, isPersistent: false);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                AddErrors(result);
            }
        }

        // If we got this far, something failed, redisplay form
        model.SellingLocations = GetSellingLocations();
        return View(model);
    }

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-identity


    【解决方案1】:

    您需要 ApplicationUser 中的 SellingLocationId 并配置您的外键关系。当您创建一个新的 ApplicationUser 时,您只需填写 SellingLocationId 而不是虚拟对象 位置Location 由 EF 在插入后或查询新的 ApplicationUser 时填写。

    此外,对于要在数据库中重复的 SellingLocation,这必须意味着 SellingLocationID 不是唯一身份。必须如此。

    【讨论】:

    • 我有点不清楚,虽然重复的行有不同的 ID,但其余的是重复的数据。我和其他两个实体一起做了这个,EF 设法弄清楚我想要做什么。在我的代码优先模型中放入 fk 和 pk 很好,但是我认为当添加一个名为 Id 的字段时,它会自动将其构造为主键。感谢您的回复。
    • 又检查了 fk 和 pk,所有 fk 和 pk 都在那里,因为我使用了导航属性并将 pk 命名为 Id。这可能是身份实体框架实现中的错误吗?
    • 您是否按照我的建议将 SellingLocationId 添加到 ApplicationUser 并将其设置在新的 ApplicationUser 而不是 Location 中。
    【解决方案2】:

    我发现了问题。我使用了两种不同的上下文对象,一种用于 UserManager,另一种用于在我的 Register post 方法中查找 SellingLocation 对象。

    更改 AccountController 的构造函数并捕获对传递给 UserStore 的上下文的引用,该上下文传递给 UserManager 解决了问题。当 db 对象是对 UserManager 中上下文的引用时,问题中的代码现在可以工作。

    【讨论】:

    • 如果你发布了功能代码,你会得到+1
    猜你喜欢
    • 2015-02-16
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 2016-10-13
    • 2016-04-20
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    相关资源
    最近更新 更多