需要帮助来解释Readonly \ ScaffoldColumn(false)
请帮助这样一个问题,而不是严格的判断,因为我是MVC的新手: 我有一个模型,用于通过ID在我的数据库中存储用户名需要帮助来解释Readonly ScaffoldColumn(false)
public class Names
{
public int NameId { get; set; }
public string Username { get; set; }
}
, 一个conrtoller
[HttpPost]
public ActionResult EditforModel(Names Name)
{
if (ModelState.IsValid)
{
db.Entry(Name).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(Name);
}
添加和编辑视图 增加运作良好,问题是有关编辑 我用
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend> legend </legend>
@Html.EditorForModel()
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
编辑我的模型。 当试图去这个视图我看到一个编辑器为Id和用户名,但如果我填写Id - 我有错误,因为没有这样的ID在数据库中的条目。 Ok.Let查找属性以隐藏编辑器。 [ScaffoldColumn(false)]类似于是否为Id提供编辑器的标记。 应用到我的模型我从我的View.Try另一个attr“0”ID发帖。 [ReadOnly(true)]使字段成为只读字段。但在同一时间,我在发布Id时得到了“0”。 修改视图我放在一个编辑的每个字段模型
@Html.HiddenFor(model => model.NameId)
@Html.EditorFor(model => model.Username)
但使用它是危险的,因为有些用户可以发表错误编号throgh请求后。
我不能使用[ScaffoldColumn(false)]在控制器的[Httppost]动作中应用Id,通过在DB中搜索适当的用户条目,因为名称已更改。 我不相信@ Html.HiddenFor是唯一的出路。但找不到一个:(
正如你所提到的“[ScaffoldColumn(false)]是像是一个标记是否呈现编辑器为Id或不”)和[ReadOnly (true)]意味着这个属性在绑定模型时会被默认模型绑定器排除
问题是HTTP协议是无状态协议,这意味着当用户将编辑表单发布到MVC控制器,这个控制器不知道他正在编辑哪个对象,除非你在从用户接收到的请求中包含一些标识符给你的对象,但包括真实对象Id不是你提到的原因的好主意(有人可以发布另一个ID)。
一个可能的解决方案可能是将具有加密标识的视图模型发送到视图,并在控制器中解密该标识。
视图模型为对象可能是这样的:
public class UserViewModel
{
[HiddenInput(DisplayValue = false)]
public string EncryptedId { get; set; }
public string Username { get; set; }
}
所以你HTTPGET操作方法将
[HttpGet]
public ActionResult EditforModel()
{
// fetching the real object "user"
...
var userView = new UserViewModel
{
// passing the encrypted Id to the ViewModel object
EncryptedId = new SimpleAES().EncryptToString(user.NameId.ToString()),
Username = user.Username
};
// passing the ViewModel object to the View
return View(userView);
}
不要忘记更改模型的视图是ViewModel
@model UserViewModel
现在HttpPost操作方法将接收UserViewModel
[HttpPost]
public ActionResult EditforModel(UserViewModel Name)
{
if (ModelState.IsValid)
{
try
{
var strId = new SimpleAES().DecryptString(Name.EncryptedId);
var id = int.Parse(strId);
// select the real object using the decrypted Id
var user = ...Single(p => p.NameId == id);
// update the value from the ViewModel
user.Username = Name.Username;
db.Entry(user).State = EntityState.Modified;
}
catch (CryptographicException)
{
// handle the case where the encrypted key has been changed
return View("Error");
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(Name);
}
当用户试图更改加密密钥时,解密将失败抛出CryptographicException,您可以在catch块中处理它。
你可以在这里(不要忘记来解决关键和Vector数组的值)找到SimpleAES加密类: Simple insecure two-way "obfuscation" for C#
PS: 这个答案是基于亨利森如下回答: Asp.net MVC 3 Encrypt Hidden Values
将id发布到隐藏的输入或操作方法参数中确实不是危险的。什么是危险的是不验证当前用户实际上可以修改传递的ID。 – dotjoe 2013-12-11 21:02:16