【问题标题】:ASP.NET validation fails - displayed elements change visibilityASP.NET 验证失败 - 显示的元素更改可见性
【发布时间】:2013-09-10 22:53:07
【问题描述】:

我有一个客户端 Javascript,我在 ASP.NET 页面中使用它来设置数据列表中几个项目的可见性。基本上,当项目 1 可见时,项目 2 应该被隐藏,反之亦然。此代码还根据客户端周围字段的可见性启用/禁用一些 ASP.NET 必需的字段验证器。

代码工作正常除非我遇到 ASP.NET 验证错误。当验证失败时,这些字段将重置为默认可见性(隐藏)。

我已排除这是回发,因为当问题发生时我的服务器端断点不会受到影响。这似乎与客户端脚本有关。

由于页面从不回发,服务器端修复程序已发布。我想知道如何从 Javascript 的角度来做到这一点?有没有办法在验证脚本触发时触发自定义代码?

我考虑过使用 cookie,但我认为这对我没有帮助,除非我可以挂钩到验证事件。

代码如下...

function handleDropDown(e, a, b, c, v1, v2, h1, h2) {
    var i = parseInt(c) + 2;
    var x = parseInt(c) + 3;

    if (e.value == "Yes") {
        document.getElementById(i).style.display = "inline";
        document.getElementById(i).style.visibility = "visible";

        document.getElementById(x).style.display = "none";
        document.getElementById(x).style.visibility = "hidden";

        document.getElementById(a).focus();

        //Enable validator if needed
        var oVal1 = document.getElementById(v1);
        var oVal2 = document.getElementById(v2);

        var oVis1 = document.getElementById(h1);
        var oVis2 = document.getElementById(h2);

        ValidatorEnable(oVal1, true);
        if (oVis1 != null) {
            oVis1.value = "true";
        }
        ValidatorEnable(oVal2, false);
        if (oVis2 != null) {
            oVis2.value = "false";
        }
       }
    else if (e.value == "No") {
        document.getElementById(x).style.display = "inline";
        document.getElementById(x).style.visibility = "visible";

        document.getElementById(i).style.display = "none";
        document.getElementById(i).style.visibility = "hidden";

        document.getElementById(b).focus();

        //Enable validator if needed
        var oVal1 = document.getElementById(v1);
        var oVal2 = document.getElementById(v2);

        var oVis1 = document.getElementById(h1);
        var oVis2 = document.getElementById(h2);

        ValidatorEnable(oVal1, false);
        if (oVis1 != null) {
            oVis1.value = "false";

        }
        ValidatorEnable(oVal2, true);
        if (oVis2 != null) {
            oVis2.value = "true";
        }
    }
}

ASPX 标记 sn-p: **

             <span id="spTxtAnswer" class="required" visible="false" runat="server">*</span>
                        <asp:TextBox ID="txtAnswer" Text='<%# Bind("Answer") %>' runat="server" 
                                   TextMode="MultiLine" Height="76px" MaxLength="2000" Width="370px" Visible="false"  >
                        </asp:TextBox>
                        <asp:RequiredFieldValidator ID="valTextBox" ErrorMessage="This question is required." Enabled="false"
                        Display="Static" ControlToValidate="txtAnswer" runat="server" ValidationGroup="Request" />
                        <asp:RequiredFieldValidator ID="valAnswer" ControlToValidate="txtAnswer" ErrorMessage="<br />Other description is required."
                        Display="Static" enabled="false" runat="server"  ValidationGroup="Request" />
                        <span id="spDdlAnswer" class="required" visible="false" runat="server">*</span>
                        <asp:DropDownList ID="ddlAnswer" Visible="false" runat="server" />
                        <asp:RequiredFieldValidator ID="valDropDown" ControlToValidate="ddlAnswer" Enabled="false"
                        ErrorMessage="This field is required." Display="Static" runat="server"
                         InitialValue="(Select)"  ValidationGroup="Request" />
                        <asp:HiddenField ID="hfQuestionID" Value='<%# Bind("QuestionID") %>' runat="server" />
                        <asp:HiddenField ID="hfAnswer" Value='<%# Bind("Answer") %>' runat="server" />
                        <asp:HiddenField ID="hfRequired" Value='<%# Bind("Required") %>' runat="server" />
                        <asp:HiddenField ID="hfVisible" Value="false" runat="server" />

CodeBehind sn-p:

TextBox tb1 = (TextBox)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("txtAnswer");
            TextBox tb2 = (TextBox)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("txtAnswer");
            RequiredFieldValidator rfv1 = (RequiredFieldValidator)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("valTextBox");
            RequiredFieldValidator rfv2 = (RequiredFieldValidator)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("valTextBox");
            HiddenField hf1 = (HiddenField)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("hfVisible");
            HiddenField hf2 = (HiddenField)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("hfVisible");

            ddl.Attributes.Add("onchange", "handleDropDown(this,'" + tb1.ClientID + "','" + tb2.ClientID + "','" + questionID + "','" + rfv1.ClientID + "','" + rfv2.ClientID + "'," + 
                "'" + hf1.ClientID + "','" + hf2.ClientID + "');");

            //When selected and viewing in edit mode, set the visibility during page load
            string script = "<script language='javascript'>";
            script += System.Environment.NewLine + "var el = document.getElementById('" + ddl.ClientID + "');";
            script += System.Environment.NewLine + "handleDropDown(el,'" + tb1.ClientID + "','" + tb2.ClientID + "','" + questionID + "','" + rfv1.ClientID + "','" + rfv2.ClientID + "');</script>";
            ClientScript.RegisterStartupScript(Page.GetType(),"startScript", script);

**

【问题讨论】:

  • 你能展示一个带有验证器的 aspx 标记的 sn-p 吗?我确实怀疑您的验证实际上发生在服务器端。您是否在 Page_Load 事件处理程序的第一行设置了断点?

标签: javascript asp.net validation


【解决方案1】:

来自另一个 stackoverflow 问题 (https://stackoverflow.com/a/11723794/704879):

“这是问题所在:当页面上加载验证器时,它会创建一些 javascript 来支持客户端验证。当您将验证器放置在默认情况下不可见的用户控件中时,并且此用户控件位于一个更新面板,它没有正确创建该 javascript。这是解决方案:在更新面板之外,我在上面做了,使用一个虚拟验证组创建一个带有虚拟文本框的虚拟验证器,如下所示:"

归功于解决方案的原始海报 (Anton Belev)。

【讨论】:

    【解决方案2】:

    我最终需要使用客户端脚本和 cookie 来设置可见性。我需要在回发后保留值,但在客户端读取它们,因此在这种情况下,视图状态并不是一个真正的选择。

    另一个相关问题是,当我尝试调用脚本在 IE10 中设置字段可见性时,它总是会在正文完成加载之前执行。我在母版页的body标签中设置了调用,现在可以正常使用了。

    【讨论】:

    • 我知道这已经很老了,但我已经提供了一个替代答案来使用 cookie 来跟踪可以更改客户端的服务器端值的状态。
    【解决方案3】:

    我知道这是旧的,但以防万一其他人像我一样遇到这种情况,我想提供一个替代 Tim 的答案,即使用 cookie 来跟踪客户端和服务器端之间的状态。

    如果您有一些需要能够读取值的 javascript,例如特定控件是否已在客户端显示/隐藏,而不是使用 cookie,我建议您在.NET 也是如此。

    多年来,我看到许多同事试图在他们的页面标记中加入隐藏字段控件,但这并不总是可靠的,因为 .NET 可以在重新加载视图状态时覆盖客户端值。我使用的解决方案似乎工作得非常可靠,而且设置起来也不难。这对于 Web 用户控件甚至服务器控件的工作方式完全相同。这使服务器端和客户端可以跨回发访问值,并尊重可能发生的值的任何客户端更改。

    下面的示例显示了布尔值、整数和字符串,但同样的方法可以用于任何可以序列化和反序列化到“字符串”值的数据类型。

    public partial class MyPage : System.Web.UI.Page
    {
        const string
            hdnFld1Nm = "hdnFld1",
            hdnFld2Nm = "hdnFld2",
            hdnFld3Nm = "hdnFld3";
    
        protected bool HiddenFieldValue1
        {
            get
            {
                object vsVal = this.ViewState["HiddenFieldValue1"];
                if (vsVal == null)
                    return false;   // Whatever you want the 'default' value to be.
                else return (bool)vsVal;
            }
            set { this.ViewState["HiddenFieldValue1"] = value; }
        }
        protected int HiddenFieldValue2
        {
            get
            {
                object vsVal = this.ViewState["HiddenFieldValue2"];
                if (vsVal == null)
                    return -1;  // Again, default value.
                else
                    return (int)vsVal;
            }
            set { this.ViewState["HiddenFieldValue2"] = value; }
        }
        protected string HiddenFieldValue3
        {
            get { return (string)this.ViewState["HiddenFieldValue3"]; }
            set { this.ViewState["HiddenFieldValue3"] = value; }
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
            // For the boolean state, we'll consider any value other than "0" or NULL to be "true".
            this.HiddenFieldValue1 = (!string.IsNullOrEmpty(this.Request[hdnFld1Nm]) && this.Request.Form[hdnFld1Nm] != "0");
    
            // For the integer, we have to parse from the string value we get from the Form collection, and deal with the potential for "null" if no value was returned.
            string sHdnVal2 = this.Request.Form[hdnFld2Nm];
            int iHdnVal2;
            if (!string.IsNullOrEmpty(sHdnVal2) && !int.TryParse(sHdnVal2, out iHdnVal2))
                this.HiddenFieldValue2 = iHdnVal2;
    
            // Getting a string value back is easy.
            this.HiddenFieldValue3 = this.Request[hdnFld3Nm];
        }
        protected void Page_PreRender(object sender, EventArgs e)
        {
            // Before the page actually renders, we want to let the .NET page renderer know that we want these three hidden field values written to the output page.
            this.Page.ClientScript.RegisterHiddenField(hdnFld1Nm, this.HiddenFieldValue1 ? "1" : "0");  // Make sure you keep your boolean logic the same.
            this.Page.ClientScript.RegisterHiddenField(hdnFld2Nm, this.HiddenFieldValue2.ToString());   // Hidden fields can only store "string" values, so we have to "ToString" our int.
            this.Page.ClientScript.RegisterHiddenField(hdnFld3Nm, this.HiddenFieldValue3);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-28
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 2018-03-23
      • 2016-11-05
      相关资源
      最近更新 更多