我已经有一段时间试着搞清楚这一点! 一般来说:我希望从我的表格中获得“只读,隐藏”属性。
我从示例中修剪了所有的不确定性:
我有以下模型
public class ChangeOrderDetailModel
{
...
...
[ReadOnly(true)]
public int OrderId { get; set; }
}
并在视图中:
@using (Html.BeginForm("SubmitChangeOrder", "Order"))
{
@Html.AntiForgeryToken()<br/>
@Html.HiddenFor(o => o.OrderId) <br />
...
...
}
现在:
在View HTML中,OrderID有一个隐藏字段...
我不希望任何人更改“OrderID”,因为它可能会导致安全问题。
我需要提交表单中的OrderID号码
问题将表单提交给Controller时
OrderController.SubmitChangeOrder(ChangeOrderDetailModel mdl){}
我发现mdl.OrderID
总是= 0 。
当我从属性中删除ReadOnly(true)
属性时,一切正常,但任何人都可以使用简单的JS更改字段的值,这很糟糕。
而且我不想只在哈希标记上进行中继,因为它也很容易被破坏:(
为什么这样工作?
我错过了什么,更好的方式来实现我喜欢的东西?
注意:可能会有多个变更单并行进行,因此会话有点问题。
感谢所有人。
答案 0 :(得分:1)
通过使用[Readonly(true)],您明确指示模型绑定器不将字段绑定到模型的属性。通过使用Html.HiddenFor
渲染属性已经在渲染的html中实现了您想要的效果。您可以在控制器操作中包含第二个参数int 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)
。您可以使用标准窗口加密来进行加密和解密。
为了极其安全,您可以为每个请求/响应会话使用不同的密钥。这将阻止更高级的流氓用户用旧版本替换OrderIdEnc。
我确信可能还有其他解决方案,但上面是我多次使用并且已经使用的模式
干杯