为了安全性和一致性,如果字段丢失,我想在回发后进行测试?在Java(特别是servlet)中,当我们执行request.getParameter(key)
时,结果是字符串值,否则如果字段丢失则为NULL。在MVC中,我创建了一个自定义验证,我称之为“ThrowOnNull”。我想要捕获的行为是:如果想要的字段丢失(null)我想抛出,否则返回成功。
考虑这个自定义验证器(不起作用):
public class ThrowOnNull: ValidationAttribute
{
public ThrowOnNull() { }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
throw new Exception(validationContext.MemberName + " field expected, but missing."));
return ValidationResult.Success;
}
}
可以在这里做我想做的事吗?(这个验证器没有按预期工作,这是因为框架将NULL赋给空值[哦亲爱的]。)
更新:根据 @emodendroket ,以下代码示例现在按预期工作:
public class ThrowOnMissing: ValidationAttribute
{
public ThrowOnMissing() { }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (!HttpContext.Current.Request.Form.AllKeys.Contains(validationContext.MemberName))
throw new Exception(validationContext.MemberName + " field expected, but missing.");
return ValidationResult.Success;
}
}
编辑:我已经清理了问题和示例代码,使其更加清晰,希望它有所帮助。
答案 0 :(得分:3)
您错过了一个重点 - 当您提交表单时,属于该表单的所有字段都会被提交。如果用户没有填写它们,那么它们就会空白,因此null的验证无法真正起作用......
你应该重新定义什么"缺少价值"装置
编辑:
经过一些讨论后,您似乎并不真正关心空值,而是关注安全性(错误的表单,缺少字段和类似的东西)。在这种情况下,您应该只使用标准 - 防伪令牌,并可能检查请求的来源。你应该比这更好。检查丢失的字段不会有所帮助,因为攻击者也可以轻松地发送这些字段。
过度/不足过账是一个真正的问题。此外,如果没有提交字段(由于某种黑客攻击或DOS攻击)
不是真的。
重叠通过控制器上的操作方法处理。它不会接受比您指定的参数更多的参数。
Underposting的处理方式与您没有填写表单中的文本字段的方式相同,如果您已正确验证模型,则再次出现问题。
DDOS攻击无法相信我,如果有人拥有足够强大的网络来导致DDOS,一些检查丢失的字段会有所帮助。只需查看有关攻击的最新案例,您就会明白,如果巨大的服务器无法承受这种情况,您当然无法像这样阻止它。
您的数据验证也不应过于昂贵。它是一个网络,人们不愿意等待太多。
答案 1 :(得分:2)
如果您需要自己的验证器,可以查看字典HttpContext.Current.Request.Form
。然后,您可以使用此代码执行您的建议:
if (!HttpContext.Current.Request.Form.AllKeys.Contains("prop"))
{
throw new Exception();
}
答案 2 :(得分:1)
我认为你在这里对事情不合情理。请注意,我说不合理的偏执,因为一点偏执是一件好事。
首先,让我们分析“威胁”并确定风险。你提出了几个论点:
如果您使用的是View Model,则第一项不是MVC中的问题。您根本无法发布视图不期望的信息(嗯,您可以,但它被忽略)。如果您没有使用视图模型(或者没有使用正确定义的视图模型),那么您可以使用绑定属性来阻止发布您不想要绑定的项目。
第二个,欠发布,如果它真的是你的模型的关注(99.999%的时间只是根据需要处理它是非常好的,但好吧,让我们采取你的论点。这里的问题不是验证属性,它是模型绑定器。您只需注册一个自定义模型绑定器,在视图模型中查找缺失值,如果它们为null则抛出。这可以通过反映绑定模型并将其与发布值进行比较,然后抛出
您的RequiredThrowIfNull方法的问题是..如果它不是必需的并且它已发布,该怎么办?根据你的论点,这仍然是一个错误。
最后,验证空vs空...你谈论昂贵的验证......我不知道你可以在这里谈论什么样的昂贵验证,但是服务器方面注意到可以考虑的属性昂贵。
你的属性不起作用的原因是因为框架已经在一个try / catch块中调用了验证属性,如果它是null,那么它就是将它视为空的机制(这种机制也可以像捕获解析一样)类型不正确时的错误,例如日期时间字段中的字符。)
.NET不是Java,尽管它在很大程度上也是类似的...尝试在.NET中重新实现Java模式会导致你的痛苦,因为许多基本的哲学都是不同的。
即使我们接受你想要捕获错误或被通知黑客攻击的论点,在大多数情况下投掷也是错误的。相反,只需记录模型绑定器中的信息并继续正常运行。只有当你绝对需要中止请求时才会抛出,并且大部分时间根本就不是这样,即使你被黑了......投掷只会让攻击者改变他们的攻击,直到他们不再获得异常。
坦率地说,这是一个过度设计,寻找问题的解决方案,并且有许多优秀的.net特定方法来处理您要解决的REAL问题。
答案 3 :(得分:0)
@ignatandrei 回答了这个问题:
默认情况下,MVC将空字符串转换为空字符串。
http://forums.asp.net/t/2006146.aspx?Custom+Validation+and+NULL