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

hug*_*dan 2 .net c# 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();
Run Code Online (Sandbox Code Playgroud)

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

这是我的AdNewReview和Save方法的代码.

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

    //
    //Persist changes to database

    public void Save()
    {
        db.SubmitChanges();
    }
Run Code Online (Sandbox Code Playgroud)

我的问题如下:

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

Dan*_*eny 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();
Run Code Online (Sandbox Code Playgroud)

还要注意使用的安全隐患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();
Run Code Online (Sandbox Code Playgroud)

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

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

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

编辑:

我只是在寻找更多关于此的信息,并发现这篇文章:

ASP.NET MVC UpdateModel容易受到黑客攻击?

看来你也可以在类上列出属性,这似乎是一个更好的可维护性的地方:

[Bind(Include="MyProp1,MyProp2,MyProp3")]
public partial class MyEntity { }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.很好的答案.我甚至没有想到安全问题. (2认同)