Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As you mentioned "[ScaffoldColumn(false)] is something like a marker whether to render an editor for Id or not", and [ReadOnly(true)] means that this property will be excluded by the default model binder when binding your model.</p> <p>The problem is that the HTTP protocol is a stateless protocol, which means that when the user posts the edit form to the MVC Controller, this controller has no clue which object he was editing, unless you include some identifier to your object in the request received from the user, though including the real object Id isn't a good idea for the reason you mentioned (that someone could post another Id). </p> <p>A possible solution might be sending a View Model with an encrypted Id to the View, and decrypting this Id in the controller.</p> <p>A View Model for your object might look like this :</p> <pre><code>public class UserViewModel { [HiddenInput(DisplayValue = false)] public string EncryptedId { get; set; } public string Username { get; set; } } </code></pre> <p>So your HttpGet action method will be </p> <pre><code> [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); } </code></pre> <p>Don't forget to change the model for your View to be the ViewModel</p> <pre><code>@model UserViewModel </code></pre> <p>Now the HttpPost action method will be receiving a UserViewModel</p> <pre><code> [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 =&gt; 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); } </code></pre> <p>When the user tries to change the encrypted key, the decryption will fail throwing a CryptographicException where you can handle it in the catch block.</p> <p>You can find the SimpleAES encryption class here (don't forget to fix the values of Key and Vector arrays): <a href="https://stackoverflow.com/questions/165808/simple-2-way-encryption-for-c-sharp#answer-212707">Simple insecure two-way &quot;obfuscation&quot; for C#</a></p> <p>PS: This answer is based on the following answer by Henry Mori: <a href="https://stackoverflow.com/questions/8964312/asp-net-mvc-3-encrypt-hidden-values#answer-8964466">Asp.net MVC 3 Encrypt Hidden Values</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload