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();
我创建了一个派生自 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();