我正在使用MVC3和EF4编写Web应用程序。我正在使用如下所示的动作标题来捕获用户提交的表单值。
<HttpPost()>
Public Function Edit(ByVal prod as Product) As ActionResult
我使用以下代码更新记录。
db.Attach(prod)
db.ObjectStateManager.ChangeObjectState(prod, EntityState.Modified)
db.SaveChanges()
我在prod对象中获取提交的值,我在数据库中更新。问题是有些用户不允许修改产品中的某些字段,比如ProductCost。我已禁用HTML中此类字段的文本框。但由于它是客户端,用户可以使用Firebug等工具轻松启用它并修改值。
我能提出的唯一解决方案是从数据库中检索现有记录并将其ProductCost值复制到prod.ProductCost中。但我不喜欢触发查询来实现这一目标。有没有更好的方法来实现这一目标?
修改:我找到了以下链接来更新特定字段。 How to update only one field using Entity Framework?
您可以使用以下代码修改特定字段。
context.ObjectStateManager.GetObjectStateEntry(user).SetModifiedProperty("FieldName");
现在问题是我是否必须为用户能够修改的每个字段编写上述语句?如果是,假设产品型号有10个字段(1个主键),并且允许用户修改除主键之外的所有字段,我需要编写9个语句?是否有一种方法可以一次指定多个属性。或者更好的是指定未修改的属性。 (注意:我知道我可以在一个字段名称数组上运行循环,以避免编写9个语句。我要求一种替代方法,而不是重构上面的方法)
答案 0 :(得分:2)
永远不要信任客户数据。始终拥有服务器代码来验证输入并执行适当的操作。
我会创建单独的重载我的Respiratory方法以不同的方式更新产品,然后检查当前用户的访问类型是什么,如果他是管理员,我会调用更新所有内容的重载,如果他是经理,我将调用更新name,imageUrl和price的方法,如果他是员工,我将调用仅更新名称和ImageURL的方法
[HttpPost]
public ActionResult Edit(Product prod)
{
if(ModelState.IsValid)
{
string userType=GetCurrentUserTypeFromSomeWhere();
if(userType=="admin")
{
repo.UpdateProduct(prod);
}
else if(userType=="manager")
{
repo.UpdateProduct(prod.ID, prod.Name, prod.ImageUrl, prod.Price);
}
else if(userType=="employee")
{
repo.UpdateProduct(prod.ID, prod.Name, prod.ImageUrl);
}
return RedirectToAction("Updated",new {id=prod.ID});
}
}