【问题标题】:ASP.NET MVC Passing data aroundASP.NET MVC 传递数据
【发布时间】:2010-11-18 04:57:37
【问题描述】:

大家好,我正在使用 ASP.NET MVC 和实体框架。我想知道将数据从控制器传递到视图然后返回的最佳方法是什么。我会解释得更好一点:

我有一个用于创建新“收据”对象的操作

        [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 将其返回,但这感觉不对。从技术上讲,有人可以进去,更改隐藏的值并重新提交帖子。然后我可以进行检查以确保所有内容都应该在它所属的位置,但这也感觉像是再次访问数据库以获取我曾经获得过的信息。

如果有人能详细说明将数据从模型传递到视图再到控制器的标准方式,那就太好了。感谢您的时间和帮助!

【问题讨论】:

    标签: c# asp.net-mvc entity-framework-4


    【解决方案1】:

    如果您担心有人胡乱使用隐藏字段值来影响其他记录,请填充 ID 值并在隐藏字段中对其进行加密,然后在回发时解密。

    【讨论】:

    • +1,这是主要答案,我在答案周围添加了一些更直接的帮助
    • 这看起来确实是一个很好的解决方案,可以真正防止篡改等等,我问得更多,因为看起来我不应该在表单中乱扔隐藏字段,而是以某种方式保留原来的值发送到视图进行往返。我可能是错的,但我想这就是发布问题的重点:-) 我肯定也会考虑这样做。谢谢你的信息!
    • 如果您不想在页面中使用 id 字段,您仍然需要设计一些其他方式将 id 传递给客户端,以便可以将其传回在回发。没办法。
    • 是的,它必须存在于视图中的某个地方,否则模型绑定上的 id 将为空。哎呀!
    • @OP 之前是一名 webforms 开发人员并使用 webforms 和 viewstate 我总是觉得在页面上使用隐藏字段是不干净的,但在使用 MVC 处理隐藏字段之后做的越来越多这就是互联网的本意。
    【解决方案2】:

    我最近刚刚在我现有的一个应用程序中添加了这样的功能。这将扩展@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)
    

    那么对于您的业务对象到视图模型的映射,除了您想要计算成本 + 私钥 + 可预测的盐值(例如收据本身的 ID)的 Sha256 哈希(或其他哈希)的 CostHash 之外,它很简单.您想要包含对象的 ID 或其他一些变量但已知值的原因是,您的系统用户无法绕过您的散列。

    如果你只使用原始值 + 私钥,如果成本是 10 美元,那么每次 10 美元的输出都是一样的。这将允许人们轻松地从不同的收据中转换成本值和 CostHash 值,但是如果您将 ID 添加为盐的一部分,则收据 1 的 10 美元的哈希值将不同于收据 2 的 10 美元。如果您在同一个对象上有许多相似的值需要保护,但您仍然担心用户可能会获取 Cost 和 CostHash 值并将它们移动到不同的行项目中,您需要在 salt 中添加更多内容,例如属性名称项目等。

    当视图模型被发送回控制器时,您想要计算 Cost 的预期哈希值并将其与 CostHash 属性进行比较并验证它们是否相等。如果它们不同,则意味着试图篡改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-08
      • 2020-07-05
      • 2018-02-18
      • 2014-06-11
      • 2010-10-23
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多