大家好,我正在玩ASP.NET MVC和Entity Framework。我想知道什么是处理从控制器到视图再返回数据的最佳方法。我会更好地解释一下:
我有一个用于创建新“收据”对象的操作
[Authorize]
public ActionResult CreateReceipt(int id)
{
//I create the receipt object
Receipt newReceipt = new Receipt();
// assign some information about the owner of the receipt
// and the group that it belongs to
newReceipt.Group = group;
newReceipt.Owner = user;
//send off to the view to be displayed
return View(newReceipt);
}
所以我基本上创建一个收据并预先填写一些信息(包括授权用户和一些组ID信息)然后我可以将其发送到具有各种表单元素的视图,让用户填写其他缺失的信息字段并提交以便添加新收据。如果收据对象中的所有字段都显示在表单上,这一切都很有效。
如果我删除了用户不应该触摸的内容的表单元素(例如组号,收据所属的用户ID等等),那么当我提交表单并将其提取时在控制器中:
[HttpPost]
[Authorize]
public ActionResult CreateReceipt(Receipt receipt)
{
if (ModelState.IsValid)
{
using (EntityFrameworkEntities context = new EntityFrameworkEntities)
{
context.AddToReceipts(receipt);
context.SaveChanges();
}
return RedirectToAction("Index");
}
return View(receipt);
}
然后,我填写并发送到视图的所有方便的预加载信息都没有回复帖子。我知道我可以将UserID或GroupID放入隐藏字段,然后使用POST返回,但这感觉不对。从技术上讲,有人可以进去,更改隐藏的值并重新提交帖子。然后我可以检查以确保一切都应该在它所属的位置,但这也感觉就像是另一次访问数据库以获取我已经获得的信息。
如果有人能详细说明从模型到视图到控制器传递数据的标准方法,那就太棒了。感谢您的时间和帮助!
答案 0 :(得分:5)
如果您担心某人使用隐藏字段值来影响其他记录,请填充ID值并在隐藏字段中加密,然后在回发时解密。
答案 1 :(得分:3)
我最近刚刚在我现有的一个应用程序中添加了这样的功能。这将扩展到@Dave Swersky
的答案假设
的业务对象Receipt
ID
Cost
ShippingAddress
我会有一个ViewModel
ReceiptViewModel
ID
Cost
CostHash
ShippingAddress
您的观点会有类似
的内容Html.HiddenFor(m => m.Id)
Html.HiddenFor(m => m.CostHash)
Html.LabelFor(m => m.Cost)
Html.LabelFor(m => m.ShippingAddress)
然后,为了将业务对象映射到viewmodel,除了要计算Cost +私钥+可预测盐值的Sha256哈希(或其他哈希)(例如收据本身的ID)的CostHash之外,它是直接的。 。您希望包含对象的ID或其他变量但已知值的原因是系统用户无法绕过您的散列。
如果您只使用原始值+私钥,如果成本为10美元,则每次10美元的输出结果相同。这将允许一个人从不同的收据中轻松转换Cost值和CostHash值,但是如果您将ID添加为salt的一部分,则Receipt 1的$ 10的哈希值将不同于Receipt 2的$ 10。如果您在同一对象上有许多类似的值要保护,您仍然担心用户可以获取Cost和CostHash值并将它们移动到说不同的行项目,则需要向salt添加更多内容,例如属性名称项目等。
当视图模型发送回控制器时,您希望计算Cost的预期哈希值,并将其与CostHash属性进行比较,并验证它们是否相等。如果它们不同意味着企图篡改。