ASP.net 从 PostBack 恢复 JavaScript 创建的属性

ASP.net Recover JavaScript Created Attribute from PostBack

我创建了一个派生自 TextBox 的控件。在 class 上添加了对 Javascript 代码的调用,当文本内容更改时,它会向控件添加一个名为 "post" 且值为 "true" 的属性。我想收集那个值。

到目前为止我有这个:

ASP

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="CWEB.Web.UI.USR.DefPage" %>
<%@ Register TagPrefix="Controls" Namespace="CWEB.Web.Controls" Assembly="Web" %>
<html>
<head>
    <script type="text/javascript">
        function SetPost(element){if(!element.hasAttribute('post')){z=document.createAttribute('post');z.value='true';element.setAttributeNode(z);}else{element.setAttribute('post','true');}}
    </script>
</head>
<body>
    <Controls:TextBox runat="server" ID="abc" />
</body>
</html>

CodeBehind(和派生的 TextBox class)

using SysWeb = global::System.Web.UI;
using CtrWeb = global::CWEB.Web.Controls;
namespace CWEB.Web
{
    internal static class Binder
    {
        internal const string PostableKey = "post";
        internal const string AuxFieldKey = "_ck";
        internal static bool GetCheck(string ck) { return (ck != null && ck != "" && (ck == global::CWEB.Data.Fields.Boolean.ValueTrue || ck.Contains("t") || ck.Contains("v"))); }

        private static bool GetCheckInput(CtrWeb.Controls.Generic.FieldControl Control, ref bool Found)
        {
            if (Control == null || Control.Page == null) { Found = false; }
            else
            {
                string value = Control.Page.Request.Form[Control.ClientID + CtrWeb.Binder.AuxFieldKey]; //If then it's child is null, it means it's unchecked.
                Found = (value != null && value != "");
                return ((Found) ? (value == "1" || value == "on" || value.Contains("t")) : false);
            }
            return false;
        }

        internal static bool GetCheck(CtrWeb.Controls.Generic.FieldControl Control, bool OutSideInput, string ViewStateKey = CtrWeb.Binder.CheckAttribute)
        {
            string value = Control.Page.Request.Form[Control.UniqueID]; //If the main control exists then it's child shal too.
            if (value == null || value == "") { return CtrWeb.Binder.GetCheck((string)Control.GetViewState()[ViewStateKey]); }
            else if (OutSideInput)
            {
                bool Found = false;
                return CtrWeb.Binder.GetCheckInput(Control, ref Found);
            } else { return CtrWeb.Binder.GetCheck((string)Control.GetAttributes()[ViewStateKey]); }
        }

        internal static void SetCheck(CtrWeb.Controls.Generic.FieldControl Control, bool OutSideInput, string ViewStateKey = CtrWeb.Binder.CheckAttribute)
        {
            bool FValue = CtrWeb.Binder.GetCheck(Control, OutSideInput, ViewStateKey: ViewStateKey);
            Control.GetViewState()[ViewStateKey] = ((FValue) ? "true" : "false");
        }
    }

    namespace Controls
    {
        public interface FieldControl
        {
            string ClientID { get; }
            string UniqueID { get; }
            SysWeb.Page Page { get; }
            SysWeb.AttributeCollection GetAttributes();
            SysWeb.StateBag GetViewState();
        }

        public class TextBox : SysWeb.WebControls.TextBox, CtrWeb.FieldControl
        {
            public bool Postable
            {
                get { return CtrWeb.Binder.GetCheck(this, false, ViewStateKey: CtrWeb.Binder.PostableKey); }
                set { CtrWeb.Binder.SetCheck(this, false, ViewStateKey: CtrWeb.Binder.PostableKey); }
            }

            protected override void LoadViewState(object savedState)
            {
                this.BaseLoadViewState(savedState);
                this.Postable = CtrWeb.Binder.GetCheck(this, false, ViewStateKey: CtrWeb.Binder.PostableKey);
            }

            protected override void OnInit(global::System.EventArgs e)
            {
                if (!this.Page.IsPostBack)
                {
                    this.Attributes.Add("onchange", "SetPost(this)");
                    this.Attributes.Add(MdWeb.Binder.PostableKey, "false");
                }
                base.OnInit(e);
            }
        }
    }

    namespace UI.USR
    {
        public class DefPage : SysWeb.Page { protected CtrWeb.TextBox abc; }
    }
}

有些代码没有复制到这里,因为它们与问题无关。

为了将该数据发布到服务器,您必须将其存储在表单值中。

HTML 元素未全部发布到服务器。只有 key/value 对表单元素是。 (WebForms 正试图 欺骗您 以为 整个页面 已发布到服务器,但这是一个谎言。)

给页面添加一个隐藏的表单域,就这么简单:

<asp:Hidden id="someHiddenField" />

然后在 JavaScript 中设置该字段的值:

document.getElementById('<%= someHiddenField.ClientID %>').value = 'true';

然后当页面回发到服务器时,'true' 值将在该隐藏字段中:

someHiddenField.Value

asp:隐藏不存在。只有表单元素才能实际回发数据。如果设置了 runat=server,服务器端将获取回发数据并将其加载到表单元素中。

在标记中或 html:

<input type="hidden" runat="server" ID="txtHiddenDestControl" />

javascript:

document.getElementById('<%= txtHiddenDestControl.ClientID %>').value = '1';

隐藏代码:

string postedVal = txtHiddenDestControl.Value.ToString();