Как вы упомянули, «[ScaffoldColumn (false)] является чем-то вроде маркера, отображать ли редактор для идентификатора или нет», а [ReadOnly (true)] означает, что это свойство будет исключено связывателем модели по умолчанию при привязкеВаша модель.
Проблема в том, что протокол HTTP является протоколом без сохранения состояния, что означает, что когда пользователь отправляет форму редактирования на контроллер MVC, этот контроллер не имеет ни малейшего представления, какой объект он редактировал, если только вы не включилинекоторый идентификатор вашего объекта в запросе, полученном от пользователя, хотя включение реального идентификатора объекта не является хорошей идеей по той причине, которую вы упомянули (что кто-то может опубликовать другой идентификатор).
Возможным решением может быть отправка модели представления с зашифрованным идентификатором в представление и расшифровка этого идентификатора в контроллере.
Модель представления для вашего объекта может выглядеть следующим образом:
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.
YouЗдесь можно найти класс шифрования SimpleAES (не забудьте исправить значения массивов Key и Vector): Простая небезопасная двусторонняя «обфускация» для C #
PS: Этот ответна основании следующего ответа Генри Мори: Asp.net MVC 3 Шифровать скрытые значения