Asp.net mvc 3 需要帮助来解释Readonly\ScaffoldColumn(错误)
请帮我回答这个问题,不要严格评判,因为我是MVC的新手: 我有一个模型,用于在数据库中按ID存储用户名Asp.net mvc 3 需要帮助来解释Readonly\ScaffoldColumn(错误),asp.net-mvc-3,http-post,member-hiding,Asp.net Mvc 3,Http Post,Member Hiding,请帮我回答这个问题,不要严格评判,因为我是MVC的新手: 我有一个模型,用于在数据库中按ID存储用户名 public class Names { public int NameId { get; set; } public string Username { get; set; } } ,, 骗子 [HttpPost] public ActionResult EditforModel(Names Name) { if (Model
public class Names
{
public int NameId { get; set; }
public string Username { get; set; }
}
,,
骗子
[HttpPost]
public ActionResult EditforModel(Names Name)
{
if (ModelState.IsValid)
{
db.Entry(Name).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(Name);
}
添加和编辑视图
添加效果很好,问题在于编辑
我用
但是使用它是危险的,因为一些用户可以通过post请求发布错误的Id
我无法通过在DB中搜索适当的用户条目,在控制器的[Httppost]操作中使用[ScaffoldColumn(false)],因为名称已更改。。
我不相信@Html.HiddenFor是唯一的出路。但找不到:(如您所述,“[ScaffoldColumn(false)]类似于标记是否为Id呈现编辑器,[ReadOnly(true)]表示绑定模型时默认模型绑定器将排除此属性
问题在于HTTP协议是一个无状态协议,这意味着当用户将编辑表单发布到MVC控制器时,该控制器不知道他正在编辑哪个对象,除非在从用户收到的请求中为对象包含一些标识符,尽管包含真实的对象Id对MVC控制器来说不是一个好主意你提到的伊森(某人可以发布另一个Id)
一种可能的解决方案可能是向视图发送带有加密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
@model 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);
}
当用户尝试更改加密密钥时,解密将失败,并引发加密异常,您可以在catch块中处理该异常
您可以在这里找到SimpleAES加密类(不要忘记修复密钥和向量数组的值):
附言:
这个答案基于亨利·莫里的以下答案:
在隐藏的输入或操作方法参数中发布id并不危险。危险的是不验证当前用户是否可以修改传递的id。
[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);
}