如果我在代码中设置一些值,我还可以使用UpdateModel()吗?

时间:2011-10-13 14:36:43

标签: c# .net asp.net asp.net-mvc

我正在尝试为ASP.NET MVC Web应用程序实现“创建”操作方法。我知道有一个辅助方法,并已成功地在其他页面上使用它,在表单和模型之间有完美的1:1匹配。我的问题涉及我要添加的新页面需要发布在表单中捕获的值和以编程方式设置的值的组合。这是一个例子。

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

正如您在此示例中所看到的,UserID在代码中定义,其余值来自表单中的用户输入。

以下是我的AdNewReview和Save方法的代码。

    public void AddNewReview(Review review)
    {
        db.Reviews.InsertOnSubmit(review);
    }

    //
    //Persist changes to database

    public void Save()
    {
        db.SubmitChanges();
    }

我的问题如下:

  1. 在这种情况下,我仍然可以使用UpdateModel()辅助方法吗?如果是这样,请举例说明。或者所有的值都必须来自反射形式才能正常工作?
  2. 即使在这种情况下有一种方法可以使用辅助方法,我仍然希望学习以手动方式进行操作。我需要对上面的代码进行哪些更改才能使其正常工作?

1 个答案:

答案 0 :(得分:5)

是的,你可以。

UpdateModel只是将值从Form复制到对象。你仍然可以自己改变它们。

但是,请记住,如果表单中也存在这些值,它们将被覆盖,因此您可以先调用UpdateModel

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

还要注意使用UpdateModel的安全隐患。恶意用户可能会添加不在您表单中的属性,如果匹配,它们仍会在模型上设置。

您可以通过使用需要更新string[]个白名单属性的重载来避免这种情况,以确保只更新允许用户修改的内容。

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

如果您想要更安全类型的东西,您还可以创建一个仅包含要更新的属性的接口,并将其作为泛型类型arg传递:

public interface IReviewEditableFields
{
    int BusinessID;
    string Comments;
    int Rating;
}

// This will only update the BusinessID, Comments and Rating properties
UpdateModel<IReviewEditableFields>(review);

编辑:

我只是在寻找更多信息,发现这篇文章:

ASP.NET MVC UpdateModel vulnerable to hacking?

您似乎还可以在课堂上列出白名单,这似乎是一个更好的可维护性的地方:

[Bind(Include="MyProp1,MyProp2,MyProp3")]
public partial class MyEntity { }