Asp.net mvc 3 需要帮助来解释Readonly\ScaffoldColumn(错误)

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

请帮我回答这个问题,不要严格评判,因为我是MVC的新手: 我有一个模型,用于在数据库中按ID存储用户名

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