6

如何覆盖或扩展标准 WebForms WebForm_OnSubmitjavascript 函数?


我在 ASP.net WebForms 网站中使用 HTML5 输入类型。用户代理(例如 Chrome、IE、Firefox)已经正确处理数据清理、备用 UI 等。

通常,当用户单击<input type="submit">按钮时,User-Agent 将停止提交,并显示 UI 以向用户指示他们的输入将是无效的:

在此处输入图像描述

WebForms 的问题在于它不使用提交按钮。相反,一切都可以通过 javascript 回发来完成,而不是提交表单:

 <asp:LinkButton ID="bbOK" Text="Save User" runat="server" OnClick="bbOK_Click"></asp:LinkButton>

其中,当呈现为客户端 html 时,将成为对 Javascript 的调用:

WebForm_DoPostBackWithOptions(...)

真正长的形式是一个锚标签:

<a id="Really_Long_Thing_ctl00_bbOK" 
   href='javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$MainContent$VistaToolbar$ctl00$bbOK", "", true, "", "", false, true))'>
   Save User
</a>

这意味着用户代理永远不会提示用户输入的元素无效。

即使form没有被“提交”,它仍然会触发一个onsubmit事件。我可以使用以下方式手动触发 HTML5 表单验证:

isValid = form.checkValidity();

理想情况下,我会在我的 ASP.web WebForms 站点中挂钩该事件:

站点主

<form runat="server" onsubmit="return CheckFormValidation(this)">

<script type="text/javascript">
   function CheckFormValidation(sender) 
   {
      //Is the html5 form validation method supported?
      if (sender.checkValidity)
         return sender.checkValidity();

      //If the form doesn't support validation, then we just assume true
      return true;
   }
</script>

除了 WebForms 基础设施删除我的 onsubmit方法处理程序,并用它自己的替换它:

<form id="ctl01" onsubmit="javascript:return WebForm_OnSubmit();" action="UserProperties.aspx?userGuid=00112233-5544-4666-7777-8899aabbccdd" method="post">

所以我自己的提交调用被忽略了。似乎深入研究WebForm_OnSubmit会导致 ASP.net WebForms 验证基础设施的一个兔子洞:

function WebForm_OnSubmit() 
{
   if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) 
      return false;
   return true;
}

它调用函数:

var Page_ValidationActive = false;
function ValidatorOnSubmit() 
{
    if (Page_ValidationActive) {
        return ValidatorCommonOnSubmit();
    }
    else 
    {
        return true;
    }
}

哪个调用,哪个调用,哪个使用,哪个检查。

只需要使用 WebForms 进行 HTML5 表单验证

问题是 WebForms 有一个巨大的基础设施,用于在提交之前检查表单,并通过标准化机制(以及我不使用的整个基础设施)向用户显示错误。它接管了onsubmit表单的事件,并且它不会(必然)<input type="submit">在过程中使用 an 。

我可以做些什么来说服 ASP.net WebForms 网站让 User-Agent 验证表单?

也可以看看

4

1 回答 1

1

Web 表单基础结构删除了处理程序,因为您尝试将其直接添加到可视化设计环境中的元素上,而 Web 表单并非旨在以这种方式工作。

捕获 on-submit 处理程序很容易,您只需要创造性地思考一下。

每当您尝试在 Web 表单环境中处理类似的事情时,您必须学会考虑在 Web 表单页面渲染管道之后出现的解决方案。如果你试图找到一个直接在 web-forms 引擎中工作的解决方案,那么 web-forms 每次都会获胜。

如果您也需要,您可以在此处重现我的确切测试用例,或者您可以挑选出您需要的位并根据需要重新使用。

步骤1

在 C# 中创建一个新的 web-forms 项目(如果需要,您可以在 VB 中进行,但我将我的示例作为 C#)创建项目后,右键单击您的应用程序引用,进入 NuGet 并安装查询。

不用 JQuery 也可以做到这一点,只使用本机方法,但现在是星期天,我今天很懒 :-)

第2步

向您的项目添加一个新的 Web 表单(使用添加新项目)并将其命名为“ Default.aspx ”,在此表单上添加一些文本、一个文本框、一个按钮和一个标签。

您的代码应类似于:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="jsvalidation.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    Please enter your name :
    <asp:TextBox ID="txtName" runat="server" data-jsname="username"></asp:TextBox>
    <asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit"     />
  </div>
  <asp:Label runat="server" ID="lblResult">...</asp:Label>
  </form>

</body>
</html>

然后按 F7(或双击按钮)转到表单的编辑器后面的代码。

第 3 步

将按钮处理程序的代码添加到后面的代码中。如果你的做事方式和我一模一样,你的代码应该类似于:

using System;

namespace jsvalidation
{
  public partial class Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {}

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
      if(Page.IsPostBack)
      {
        lblResult.Text = "Well hello there " + txtName.Text;
      }
    }
  }
}

此时,您可以通过按 F5 来测试是否正常工作,当您按下提交按钮时,您在文本框中输入(或未输入)的任何内容都应该与下面标签中的消息一起出现。

现在我们已经建立了一个基本的网络表单,我们只需要拦截表单提交。

第4步

正如我刚才所说,您需要跳出网络表单的框框思考。

这意味着您需要在页面呈现并发送到浏览器之后运行拦截。

web-forms 注入到 mix 中的所有 JS 通常在页面输出被允许继续之前执行,这意味着在开始的 body 标记之前。

为了让您的代码在它之后运行,您需要将您的脚本放在 html 输出的END处,以便它最后运行。

在结束正文标记之前添加以下代码,但在结束表单标记之后

<script src="/Scripts/jquery-2.1.1.js"></script>
<script type="text/javascript">

  $(document).ready(function() {

    $('form').submit(function() {

      var uninput = $('input[data-jsname="username"]');
      var username = uninput.val();

      if (username == "")
      {
        alert("Please supply a username!");
        return false;
      }

    });

  });

</script>

你们中越精明的人,会立即注意到我没有调用 HTML5 验证 API,原因是我试图让这个示例保持简单。

我检查用户名值的地方是重要的部分。

重要的是我执行检查的匿名函数返回真或假。(如果您不返回任何内容,则默认为 True)

如果您返回 false,您将阻止回发,从而允许您使用所需的任何 JS 代码来使用 HTML5 验证 API 更改表单字段。

我个人的偏好是使用 bootstrap(请参阅我的 Bootstrap 2 书的 syncfusion 免费电子书范围,即将发布 Bootstrap 3 书),您可以在其中使用框架中的特殊标记和 css 类,例如“has-errors " 适当地给事物上色。

至于使用 JQuery 选择组件,这里也有两点需要注意。

  • 1)你不应该在网页表单页面上拥有多个表单,事实上,如果我没记错的话,如果你这样做,你的应用程序将无法编译,或者最多它肯定会在运行时抛出异常。

  • 2)因为你只有一个表单,那么你可以非常安全地做出假设,即 JQuery 中的通用“表单”选择器只会选择你的主表单(不管 ID、名称、缺少或大小)并为其添加一个 onsubmit 处理程序,将始终在web-forms 完成后附加它。

  • 3)因为网络表单可以(并且通常会)破坏ID名称,使用“数据属性”向标签添加自定义位通常更容易。实际的 ASP.NET js 端验证本身也采用了完全相同的技巧,以允许 JS 代码和 .NET 代码愉快地共存于同一页面中。有很多方法可以告诉 .NET 如何命名 ID,但通常您必须在很多地方设置很多选项,而且很容易错过一个。使用“数据属性”和 JQ 属性选择器语法是一种更安全、更易于管理的方式来实现相同的目标。

概括

这不是一项艰巨的任务,但我必须承认,如果您不看网络表单围绕您构建的栅栏之外,它并不是立即显而易见的。

Web-forms 专为快速应用程序开发而设计,主要用于习惯于桌面 win-forms 模型的开发人员。虽然这些天网络表单仍然占有一席之地,但对于新的未开发应用程序,我建议也考虑其他选项,尤其是那些建立在新 HTML5 规范努力建立和完善的基础之上的选项。

于 2014-07-06T13:26:12.440 回答