我回到了9个月前我上次工作的项目,查看了我们编写的一些代码,并希望现在有更好的方法来实现这一目标......
虽然最初对jQuery的不引人注目的验证印象非常深刻,但我们最终还是要将下面的黑客(部分基于我现在不能动手的博客文章)放在一起来处理远程验证。问题在于服务器端验证过程很慢 - 通常是涉及数据库调用的任何事情 - 验证器不会等待验证方法的响应,并且会表现得好像它已经传回正面。
hack基本上是继续检查验证器是否有任何待处理请求,并且在没有任何待处理请求之前不进行,当你可以确定真正的验证结果时:
function SaveChangePassword() {
// Find form, fire validation
var $form = $("#btnSave").closest("form");
if ($form.valid()) {
//Do nothing - just firing validation
}
// Calls method every 30 milliseconds until remote validation is complete
var interval = setInterval(saveWhenValidationComplete, 30);
// Check if validation pending, save and clear interval if not
function saveWhenValidationComplete() {
// Find form validator, check if validation pending - save once remote validation is finished
var validator = $form.data("validator");
if (validator.pendingRequest === 0) {
clearInterval(interval);
//Force validation to present to user (this will not retrigger remote validation)
if ($form.valid()) {
var closeButton = "<br/><input type='button' value='OK' style='font-size:small; font-weight:bold; float:right;' onclick=\"$('#changePasswordDialog').dialog('close');\" class='greenbutton' />";
// If form is valid then submit
$.ajax(
{
type: "POST",
url: "/Account/SavePassword",
data: $form.serialize(),
success: function (result) {
var successMessage = "<div style='text-align:center; margin-top: 10px;'>" + result + "<div>";
$("#changePasswordDialog").html(successMessage + closeButton);
},
error: function (jqXhr, textStatus, errorThrown) {
// Populate dialog with error message and button
var errorMessage = "<div style='text-align:center'>Error '" + jqXhr.status + "' (Status: '" + textStatus + "', errorThrown: '" + errorThrown + "')<div>";
$("#changePasswordDialog").html(errorMessage + closeButton);
}
});
}
// Else validation will show
}
// Else don't save yet, wait another 30 miliseconds while validation runs
};
// Prevent default and stop event propagation
return false;
}
我希望在过去的9个月中有一些发展,这已经不再需要了!任何想法欢迎,如果我能提供任何进一步的细节,请告诉我。
答案 0 :(得分:2)
虽然您可以为用户提供客户端验证,但您应始终(始终!)在服务器上重新验证。用户很容易禁用javascript或以其他方式伪造无效的POST到您的控制器操作,如果您不检查服务器端的内容,则会为用户创建破坏数据的机会在你的系统中。
幸运的是,ASP.NET MVC中的大多数验证都是为您完成的。如果您的控制器操作如下所示:
public ActionResult SaveSomething(Something thing)
{
if(!ModelState.IsValid)
{
return View("EditSomething", thing);
}
// otherwise, save something...
}
...然后您就会发现问题,即用户提供的数据无法绑定到您的数据属性,以及[Required]
和{{1}等属性验证的内容}}。但是,某些形式的验证不会自动为您检查。 [StringLength(x)]
就是其中之一。
如果您有一个[Remote]
属性指向这样的控制器操作:
[Remote]
...那么你在提交动作中也应该有这样的东西:
public ActionResult CheckThingCodeValidity(string code)
{
return Json(_thingCodeChecker.ThingCodeWorks(code), JsonRequestBehavior.AllowGet);
}
这样,您的标准服务器端验证技术可以将视图发送回用户,并在该属性上向他们提供错误消息,以指示他们需要修复的内容。
如果您这样做,那么您不必担心在提交表单时是否仍在进行异步验证检查。如果您的客户端验证通常无法通过缺陷,网络问题或恶意用户干预,那么无关紧要。您仍然会阻止他们提交无效的内容,他们仍然可以很好地了解他们提交内容无效的原因。