我正在尝试为我的一个用户编辑数据。但是,每当我编辑某些内容时,隐藏的密码也会被更改并显然设置为null,这会导致用户下次无法登录时登录。我知道我可能已经能够通过使用ViewModels来解决这个问题,但我试图在没有它的情况下解决这个问题。
模型
public class User : IdentityUser
{
[Display(Name = "First name")]
public String FirstName { get; set; }
[Display(Name = "Last name")]
public string LastName { get; set; }
public string Email{ get; set; }
}
请注意,User-class从IdentityUser扩展,其中包含密码变量。
在控制器中修改
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "FirstName,LastName,Email,PhoneNumber")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
查看编辑
<div class="form-horizontal">
<h4>User</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PhoneNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PhoneNumber, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PhoneNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
}
据我所知,Edit-method中的Bind-parameter将变量列入白名单或将其列入黑名单进行编辑。因此,我删除了用户在Bind中不应编辑的所有值。
答案 0 :(得分:1)
这里有几个问题。首先,首先不要将这些字段呈现给用户。我无法想象用户应该能够编辑他们的'#34;锁定&#34;状态或其哈希密码。仅在UI中包含用户实际应该修改的字段。天哪,即使这有可怕的想法写满了它:
@Html.HiddenFor(model => model.Id)
您不仅允许用户编辑有关其用户记录的所有内容,而且您还允许他们指定其他用户记录编辑。因此,系统中的任何用户都可以完全编辑系统中的任何其他用户。
希望你看到这是一件坏事:)
现在,您可以(并且通常必须)在隐藏字段中包含标识符。由于你还在做什么,上述问题主要是不好的:
db.Entry(user).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
您完全并且隐含地信任用户发送给您的任何内容,以成为数据库的完整,正确和完整的记录。无论用户发送给您什么,都可以替换现有记录。那是......不好。
这种方法适用于某些模型,但肯定不适用于用户安全数据等敏感模型。
相反,获取现有记录并仅编辑必要的字段。像这样:
var existingUser = db.Users.Single(u => u.Id == currentUserId);
existingUser.FirstName = user.FirstName;
existingUser.LastName = user.LastName;
// etc.
db.SaveChanges();
请注意,我使用了一个名为currentUserId
的未定义变量。 不要使用model.Id
,因为这又允许用户指定他们想要编辑的其他用户。通过当前登录的会话确定当前用户ID,而不是通过他们在表单中发送的内容。但是,您目前可识别您的用户。 (User.Identity
?)
简而言之......