初衷
刚在弄一个asp.net web form的用户注册、登录界面(asp.net mvc的高手请不要喷 :]),涉及的两个界面都有大量的验证工作要做。既然现在jQuery那么流行,赶紧找到了jQuery Validate插件并迅速的过了一下它的基础文档,开始上手!
中间完成的代码
Register.aspx
<%@ Page Language="C#" AutoEventWireup="true" EnableEventValidation="false" CodeBehind="Register.aspx.cs" Inherits="YourNameSpace.Web.Register" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>注册</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="scm" runat="server" AjaxFrameworkMode="Disabled"> <Scripts> <asp:ScriptReference Path="~/Scripts/jquery-1.8.2.js" /> <asp:ScriptReference Path="~/Scripts/jquery.validate.js" /> <asp:ScriptReference Path="~/Scripts/register.js" /> </Scripts> </asp:ScriptManager> <div id="mainContainer" style="width: 700px; margin: auto;"> <div class="error"> <span></span> </div> <div id="formContainer"> <fieldset class="login"> <legend class="login">注册</legend> <table> <tr> <td class="label"> <label for="username" class="login"> 用户名</label> </td> <td class="field"> <div class="div_texbox"> <asp:TextBox ID="username" runat="server" class="username required"></asp:TextBox> </div> </td> <td class="status"> </td> </tr> <tr> <td class="label"> <label for="password" class="login"> 密码</label> </td> <td class="field"> <div class="div_texbox"> <asp:TextBox TextMode="Password" ID="password" ClientIDMode="Static" runat="server" class="password required" Text="password" ></asp:TextBox> </div> </td> <td class="status"> </td> </tr> <tr> <td class="label"> <label for="password2" class="login"> 重复密码</label> </td> <td class="field"> <div class="div_texbox"> <asp:TextBox TextMode="Password" ID="password2" ClientIDMode="Static" runat="server" class="password required" Text="password" ></asp:TextBox> </div> </td> <td class="status"> </td> </tr> <tr> <td class="label"> <label for="email" class="login"> 邮箱</label> </td> <td class="field"> <div class="div_texbox"> <asp:TextBox ID="email" ClientIDMode="Static" runat="server" class="textbox required email"></asp:TextBox> </div> </td> <td class="status"> </td> </tr> <tr> <td colspan="2"> <div class="button_div"> <asp:Button ID="btnClear" OnClientClick="clearFields();return false;" runat="server" class="buttons" Text="清空" onclick="btnClear_Click" /> <asp:Button ID="btnReg" runat="server" class="buttons" Text="注册" onclick="btnReg_Click" /> </div> </td> <td></td> </tr> </table> </fieldset> </div> </div> </form> </body> </html>
Register.js
function clearFields() { if ($("form").data('validator')) { $("form").data('validator').resetForm(); } } $(document).ready(function () { jQuery.validator.addMethod("password", function (value, element) { var result = this.optional(element) || value.length >= 6 && /\d/.test(value) && /[a-z]/i.test(value); if (!result) { element.value = ""; var validator = this; setTimeout(function () { validator.blockFocusCleanup = true; //element.focus(); validator.blockFocusCleanup = false; }, 1); } return result; }, "Your password must be at least 6 characters long and contain at least one number and one character."); jQuery.validator.messages.required = ""; $("form").validate({ invalidHandler: function (e, validator) { var errors = validator.numberOfInvalids(); if (errors) { var message = errors == 1 ? 'You missed 1 field. It has been highlighted below' : 'You missed ' + errors + ' fields. They have been highlighted below'; $("div.error span").html(message); $("div.error").show(); } else { $("div.error").hide(); } }, onkeyup: false, /* submitHandler: function () { $("div.error").hide(); alert("submit! use link below to go to the other step"); }, //*/ rules: { username: { required: true, minlength: 6, maxlength: 20, remote: "ValidateHanlders/CheckHandler.ashx" }, password2: { required: true, equalTo: "#password" }, email: { required:true, remote: "ValidateHanlders/CheckHandler.ashx" } }, messages: { password2: { required: " ", equalTo: "Please enter the same password as above" }, email: { required: " ", email: "Please enter a valid email address, example: [email protected]", remote: jQuery.validator.format("{0} is already taken, please enter a different address.") } }, errorPlacement: function (error, element) { error.appendTo(element.parent().parent().next()); }, debug:false }); });
问题
花了30分钟写好了asp.net页面以及前端脚本,第一次点击注册按钮服务器端事件能响应到,但是第二次服务器端事件始终不能被触发。
在google中搜了这个问题,貌似也没有什么答案。
解决问题
还是用排除法,最后在调试服务器端代码时发现page_load方法确实是被调用了,只是控件的事件没有被触发。 用浏览器开发工具查看aspx页面,发现跟__doPostback相关的客户端脚本不见了,但是这貌似是asp.net 3.5后的一个新特性,最多说明了asp.net后端认为register.aspx页面根本不需要render __doPostback脚本。 不过确实不能放过这个线索,g一下试试运气吧。
参照stackoverflow.com一个帖子的答案,具体内容如下:
The problem was, as tdammers noted, that ASP.NET only renders the __doPostback()
javascript when it thinks it's needed, and in this case it didn't think so. The solution was given to me ina thread at forums.asp.net and was as simple as this:
Set UseSubmitBehavior="False" on the button that should submit with __doPostBack()
and not using the browser's default submit behavior.