How to Preserve/Protect Certain Fields in Edit in ASP.NET MVC
In an Edit action in ASP.NET MVC, certain fields can be hidden from user with HiddenFieldFor. However this doesn't protect the fields (such as ID, data creation date) from being edited.
For example, a model Student has fields Id开发者_如何学C, Name and Birthday. I like to allow users to update the Name, but not Id nor Birthday.
For an Edit action like this
public ActionResult Edit(Student student)
{
if (ModelState.IsValid)
{
db.Entry(student).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(student);
}
How can I prevent Id and Birthday from being edited? Thanks!
You should use a view model which contains only the properties that you want to be edited:
public class EditStudentViewModel
{
public string Name { get; set; }
}
and then:
public ActionResult Edit(StudentViewModel student)
{
...
}
Another technique which I don't recommend is to exclude certain properties from binding:
public ActionResult Edit([Bind(Exclude = "Id,Birthday")]Student student)
{
...
}
or include:
public ActionResult Edit([Bind(Include = "Name")]Student student)
{
...
}
I assume you have to have the properties in your Model so that in View you can use them to render useful information e.g. an ActionLink with ID or some readonly Text.
In this case you can define your model with an explicit binding:
[Bind(Include = "Name")]
public class Student
{
int Id { get; set; }
int Name { get; set; }
DateTime Birthday { get; set; }
}
This way when updating your model, if the user submits an extra Id it will not be bound.
Another idea I like is having your model know its bindings per scenario and have them compiler validated:
public class ModelExpression<T>
{
public string GetExpressionText<TResult>(Expression<Func<T, TResult>> expression)
{
return ExpressionHelper.GetExpressionText(expression);
}
}
public class Student
{
public static string[] EditBinding = GetEditBinding().ToArray();
int Id { get; set; }
int Name { get; set; }
DateTime Birthday { get; set; }
static IEnumerable<string> GetEditBinding()
{
ModelExpression<Student> modelExpression = new ModelExpression<Student>();
yield return modelExpression.GetExpressionText(s => s.Name);
}
}
This way in your Action when calling TryUpdateModel you can pass this information.
精彩评论