0

我已经有一段时间试图弄清楚这一点了!
通常:我想从我的表单中获取“只读、隐藏”属性。

我从示例中删除了所有不必要的内容:
我有以下模型

public class ChangeOrderDetailModel
{
...
...
    [ReadOnly(true)]
    public int OrderId { get; set; }
}

在视图中:

@using (Html.BeginForm("SubmitChangeOrder", "Order"))
{
    @Html.AntiForgeryToken()<br/>
    @Html.HiddenFor(o => o.OrderId) <br />
...
...
}

现在:

  1. 在 View HTML 中,OrderID 有一个隐藏字段...

  2. 我不希望任何人更改“OrderID”,因为它可能会导致安全问题。

  3. 我需要表单提交时的 OrderID 号...

  4. 问题当表单提交给控制器时, OrderController.SubmitChangeOrder(ChangeOrderDetailModel mdl){}
    我看到它mdl.OrderID 总是 = 0

  5. 当我ReadOnly(true)从属性中删除属性时,一切正常,但是任何人都可以使用简单的 JS 更改字段的值,这非常糟糕。
    而且我不想只在哈希令牌上中继,因为它也很容易被破坏:(

为什么它会这样工作?
我是否错过了一些东西,一种更好的方式来实现我喜欢的东西?

注意:可能有几个变更单同时进行,所以会话有点问题。

谢谢大家。

4

1 回答 1

1

通过使用 [Readonly(true)] 您明确指示模型绑定器不要将字段绑定到模型的属性。通过使用渲染属性Html.HiddenFor已经在渲染的 html 中实现了您想要的。您可以在控制器操作中包含第二个参数 asint OrderId并且模型绑定器会将值绑定到该变量

流氓用户可能仍然能够编辑 OrderId。保护它免受此类操作的一种方法是加密 OrderId 并在模型中使用加密值,随后在页面上使用。然后,一旦回发发生,您将解密加密的 OrderId。加密和解密可以封装到模型本身

@TomerW,如果我正确理解了您的问题,您的核心问题是流氓用户可以在客户端更改 OrderId 的值,我的建议是不要以裸露的形式呈现 OrderId,而是在服务器端使用密钥只在服务器上知道。您应该将 HTML 中的加密值呈现为隐藏字段。流氓用户可能仍会尝试更改关联的值,但解密会失败,并且您会知道有人试图摆弄您的值。以下是一个存根实现,

public class ChangeOrderDetailModel
{
    [ReadOnly(true)] /*You are instructing the model binder not to bind this value*/
    public int OrderId { get; set; }

    private string _OrderIdEnc;
    public string OrderIdEnc
    {
        /*Encryp*/
        get
        {
            return Encrypt(OrderId);
        }

        set
        {
            _OrderIdEnc = value;
        }
    }

    public void DecryptPayload()
    {
        /* Decrypt, and this will fail is someone has edited the value */
        OrderId = Decrypt(_OrderIdEnc);
    }
}

在您的视图模型中,使用@Html.HiddenFor(o => o. OrderIdEnc). 您可以使用标准的 windows 加密来进行加密和解密。

为了非常安全,您可以为每个请求/响应会话使用不同的密钥。这将防止更高级的流氓用户用旧版本替换 OrderIdEnc。

我确信可能还有其他解决方案,但以上是我多次使用并且有效的模式

干杯

于 2013-02-02T14:03:11.643 回答