Can I still use UpdateModel() if I'm setting some values in code?
I'm attempting to implement a "Create" action method for an ASP.NET MVC web application. I understand that there is a helper method for this and have successfully used it on other pages where there is a perfect 1:1 match between the form and the model. My question relates to a new page I am trying to add that needs to Post a combination of values captured in the form and values that are set in programatically. Here's an example.
MembershipUser user = Membership.GetUser(User.Identity.Name);
Guid guid = (Guid)user.ProviderUserKey;
review.UserID = guid;
review.BusinessID = Convert.ToInt16(Request.Form["BusinessID"]);
review.Comments = Request.Form["Comments"];
review.Rating = Convert.ToInt16(Request.Form["Rating"]);
reviewsRepository.AddNewReview(review);
reviewsRepository.Save();
As you can see in this example, the UserID is defined in code and the rest of the values come from user inputs in the form.
Here's the code for my AdNewReview and Save methods.
public void AddNewReview(Review review)
{
db.Reviews.InsertOnSubmit(review);
}
//
//Persist changes to database
public void Save()
{
db.SubmitChanges();
}
My questions are as follows:
- Can I still use the UpdateModel() helper method in this scenario? Plea开发者_开发技巧se show an example if so. Or do all of the values have to come from the form for the reflection to work correctly?
- Even if there is a way to use the helper method in this scenario, I'd still like to learn to do it the manual way. What do I need to change about my code above to make it work?
Yes, you can.
UpdateModel just copies values from the Form
to the object. You can still change them yourself.
However, bear in mind that if the values also exist in the form, they will be overwritten, so you could call UpdateModel
first.
MembershipUser user = Membership.GetUser(User.Identity.Name);
Guid guid = (Guid)user.ProviderUserKey;
// Copy form values
UpdateModel(review);
// Overwrite custom values
review.UserID = guid;
reviewsRepository.AddNewReview(review);
reviewsRepository.Save();
Also be aware of security implications of using UpdateModel
. A malicious user may add properties that weren't in your form, and they will still be set on the model if they match.
You can avoid this by using the overload that takes a string[]
whitelist of properties to update, to ensure only the ones a user is allowed to modify are updated.
MembershipUser user = Membership.GetUser(User.Identity.Name);
Guid guid = (Guid)user.ProviderUserKey;
// Copy form values
UpdateModel(review, new string[] { "BusinessID", "Comments", "Rating" });
// Overwrite custom values
review.UserID = guid;
reviewsRepository.AddNewReview(review);
reviewsRepository.Save();
If you'd like something more type-safe, you can also create an interface that contains just the properties to update, and pass that in as the generic type arg:
public interface IReviewEditableFields
{
int BusinessID;
string Comments;
int Rating;
}
// This will only update the BusinessID, Comments and Rating properties
UpdateModel<IReviewEditableFields>(review);
Edit:
I was just searching for a little more info on this, and found this post:
ASP.NET MVC UpdateModel vulnerable to hacking?
It seems that you can also whitelist properties on the class, which seems a better place for maintainability:
[Bind(Include="MyProp1,MyProp2,MyProp3")]
public partial class MyEntity { }
精彩评论