ASP.NET 自定义控件 - 自定义属性不保存回发时分配的值

发布于 2024-12-26 08:06:27 字数 4103 浏览 1 评论 0原文

我有一个自定义的 asp-net 控件,它继承自另一个控件,并且它按预期工作,但只有当我直接在标记中编码时,属性才会正确设置,因此,例如,如果我需要在运行时设置一个动态属性值,该值永远不会被设置或以某种方式丢失。

这是标记代码:

<!--related form-->
<fw:advancedformdisplay id="formDisp" runat="server" captchaenabled="true" EmailEnabled="true" EnableViewState="true" captchaprivatekey="xxxxxxxxxxxxxxxxxxxx" captchapublickey="xxxxxxxxxxxxx" captchatheme="white" SourceType="MenuItem" SourceMainId="Auto">
</fw:advancedformdisplay> 

这是控件的代码:

    [DefaultProperty("CaptchaEnabled"),ToolboxData("<{0}:AdvancedFormDisplay runat=server></{0}:AdvancedFormDisplay>"), Description("This is an enhanced FormDisplay control that inlcudes Googles Captcha control is enabled")]
public class AdvancedFormDisplay :SiteBuilder.WebControls.FormDisplay
{
    bool _CaptchaEnabled = false, sendEmail = false;
    string captchaErrorMessage = "The verification code entered is not valid. Please try again!";
    RecaptchaControl captchaControl = null;
    string captchaPrivateKey = "", captchaPublicKey = "", captchaTheme = "clean";
    string originalFormHtml = string.Empty;
    string afterText = string.Empty, beforeText = string.Empty;
    Literal litHtmlForm = null;
    string captchaErrorClass = "errorCaptcha";

    public string EmailBeforeText
    {
        get { return beforeText; }
        set { beforeText = value; }
    }

    public string EmailAfterText
    {
        get { return afterText; }
        set { afterText = value; }
    }

    public string CaptchaErrorClass
    {
        get { return captchaErrorClass; }
        set { captchaErrorClass = value; }
    }

    public bool CaptchaEnabled
    {
        get { return _CaptchaEnabled; }
        set { _CaptchaEnabled = value; }
    }

    public bool EmailEnabled
    {
        get { return sendEmail; }
        set { sendEmail = value; }
    }

    public string CaptchaErrorMessage
    {
        get { return captchaErrorMessage; }
        set { captchaErrorMessage = value; }
    }

    /// <summary>
    /// red,white,blackglass,clean
    /// </summary>
    public string CaptchaTheme
    {
        get { return captchaTheme; }
        set { captchaTheme = value; }
    }

    public string CaptchaPrivateKey
    {
        get { return captchaPrivateKey; }
        set { captchaPrivateKey = value; }
    }

    public string CaptchaPublicKey
    {
        get { return captchaPublicKey; }
        set { captchaPublicKey = value; }
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
    }


    public override void OnSaved(FormDisplayEventArgs e)
    {
        //If captcha control is enabled we need to adda  bit of code to redirect form properly
        if (CaptchaEnabled && e.Redirect && !e.SendMail)
        {
            //Do Stuff
        }

        if(sendEmail)
        {
            //Send email
        }

        base.OnSaved(e);
    }

    public override void OnSaving(FormDisplayEventArgs e)
    {
        if (CaptchaEnabled)
        {
            //Validate and do stuff
        }

        base.OnSaving(e);
    }
}

然后在我使用由标记代码创建的控件的 asp.net 页面中,在 Page_Load() 中我尝试为某些属性分配一些值,并且这些值是设置不正确,这意味着如果我设置了实例,则不会分配属性 EmailBeforeText =“somthing” 该值。

protected void Page_Load(object sender, EventArgs e)
{
    //2: Get the language of menuitem - Based on current culture setting (for by dropdownbox - change logic)
    try
    {
        currentCulture = Thread.CurrentThread.CurrentCulture.ToString();

        // Redirect if domain does not match rootnode.
        DomainChecker.CheckURL(this.Request, this.Response, currentCulture);

        if (footerArticle != null)
            footerArticle.SourceMenuId = Digimaker.Config.Custom.Get("FooterID_" + currentCulture).ToString();
    }
    catch
    {
        currentCulture = "en-GB";

        if( footerArticle != null )
            footerArticle.SourceMenuId = Digimaker.Config.Custom.Get("FooterID_" + currentCulture).ToString();
    }

我在这里缺少什么想法吗?

非常感谢您的阅读!

问候, 字节从机

I have a custom asp-net control that inherits from another one and its works as expected, though the properties are only set properly if i code them in the markup directly, so for instance if i need set a property at runtime that is some dynamic value, this value is never set or somehow lost.

Here's the markup code:

<!--related form-->
<fw:advancedformdisplay id="formDisp" runat="server" captchaenabled="true" EmailEnabled="true" EnableViewState="true" captchaprivatekey="xxxxxxxxxxxxxxxxxxxx" captchapublickey="xxxxxxxxxxxxx" captchatheme="white" SourceType="MenuItem" SourceMainId="Auto">
</fw:advancedformdisplay> 

This is the code of the control:

    [DefaultProperty("CaptchaEnabled"),ToolboxData("<{0}:AdvancedFormDisplay runat=server></{0}:AdvancedFormDisplay>"), Description("This is an enhanced FormDisplay control that inlcudes Googles Captcha control is enabled")]
public class AdvancedFormDisplay :SiteBuilder.WebControls.FormDisplay
{
    bool _CaptchaEnabled = false, sendEmail = false;
    string captchaErrorMessage = "The verification code entered is not valid. Please try again!";
    RecaptchaControl captchaControl = null;
    string captchaPrivateKey = "", captchaPublicKey = "", captchaTheme = "clean";
    string originalFormHtml = string.Empty;
    string afterText = string.Empty, beforeText = string.Empty;
    Literal litHtmlForm = null;
    string captchaErrorClass = "errorCaptcha";

    public string EmailBeforeText
    {
        get { return beforeText; }
        set { beforeText = value; }
    }

    public string EmailAfterText
    {
        get { return afterText; }
        set { afterText = value; }
    }

    public string CaptchaErrorClass
    {
        get { return captchaErrorClass; }
        set { captchaErrorClass = value; }
    }

    public bool CaptchaEnabled
    {
        get { return _CaptchaEnabled; }
        set { _CaptchaEnabled = value; }
    }

    public bool EmailEnabled
    {
        get { return sendEmail; }
        set { sendEmail = value; }
    }

    public string CaptchaErrorMessage
    {
        get { return captchaErrorMessage; }
        set { captchaErrorMessage = value; }
    }

    /// <summary>
    /// red,white,blackglass,clean
    /// </summary>
    public string CaptchaTheme
    {
        get { return captchaTheme; }
        set { captchaTheme = value; }
    }

    public string CaptchaPrivateKey
    {
        get { return captchaPrivateKey; }
        set { captchaPrivateKey = value; }
    }

    public string CaptchaPublicKey
    {
        get { return captchaPublicKey; }
        set { captchaPublicKey = value; }
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
    }


    public override void OnSaved(FormDisplayEventArgs e)
    {
        //If captcha control is enabled we need to adda  bit of code to redirect form properly
        if (CaptchaEnabled && e.Redirect && !e.SendMail)
        {
            //Do Stuff
        }

        if(sendEmail)
        {
            //Send email
        }

        base.OnSaved(e);
    }

    public override void OnSaving(FormDisplayEventArgs e)
    {
        if (CaptchaEnabled)
        {
            //Validate and do stuff
        }

        base.OnSaving(e);
    }
}

And then in my asp.net page that is using control, created by markup code, in the Page_Load() i try to assign some values to some properties and and the values aren't set properly, meaning that if i have set for isntance, the property EmailBeforeText = "somthing" this value will not be assigned..

protected void Page_Load(object sender, EventArgs e)
{
    //2: Get the language of menuitem - Based on current culture setting (for by dropdownbox - change logic)
    try
    {
        currentCulture = Thread.CurrentThread.CurrentCulture.ToString();

        // Redirect if domain does not match rootnode.
        DomainChecker.CheckURL(this.Request, this.Response, currentCulture);

        if (footerArticle != null)
            footerArticle.SourceMenuId = Digimaker.Config.Custom.Get("FooterID_" + currentCulture).ToString();
    }
    catch
    {
        currentCulture = "en-GB";

        if( footerArticle != null )
            footerArticle.SourceMenuId = Digimaker.Config.Custom.Get("FooterID_" + currentCulture).ToString();
    }

Any ideas what i'm missing here?

Thanks a lot for your reading!

Regards,
byte_slave

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

韶华倾负 2025-01-02 08:06:27

简短的回答:使用 viewstate 来保存您的自定义值!

编辑:阅读白皮书显然是一件非常困难的事情:

每个控件负责存储自己的状态,即
通过将其更改后的状态添加到其 ViewState 属性来完成。
ViewState 属性在 System.Web.UI.Control 类中定义,
这意味着所有 ASP.NET 服务器控件都具有此属性。
(当一般谈论视图状态时,我将使用小写字母
视图和状态之间有一个空间;在讨论 ViewState 时
属性,我将使用正确的大小写和代码格式的文本。)

如果您检查任何 ASP.NET 服务器控件的简单属性
您将看到属性直接读取和写入视图
状态。 (您可以通过以下方式查看 .NET 程序集的反编译源代码
使用像 Reflector 这样的工具。)例如,考虑 HyperLink Web
控件的 NavigateUrl 属性。该属性的代码如下所示
所以:

public string NavigateUrl
{
  get
  {
    string text = (string) ViewState["NavigateUrl"];
    if (text != null)
       return text;
    else
       return string.Empty;
  }
  set
  {
    ViewState["NavigateUrl"] = value;
  }
}

正如此代码示例所示,每当控件的属性为
读取时,会查阅控件的 ViewState。如果没有条目
在 ViewState 中,则返回属性的默认值。
属性赋值时,直接写入赋值的值
到视图状态。

short answer: use viewstate to persist your custom values!

edit: as reading the white-paper is obviously a really hard thing:

Each control is responsible for storing its own state, which is
accomplished by adding its changed state to its ViewState property.
The ViewState property is defined in the System.Web.UI.Control class,
meaning that all ASP.NET server controls have this property available.
(When talking about view state in general I'll use lower case letters
with a space between view and state; when discussing the ViewState
property, I'll use the correct casing and code-formatted text.)

If you examine the simple properties of any ASP.NET server control
you'll see that the properties read and write directly to the view
state. (You can view the decompiled source code for a .NET assembly by
using a tool like Reflector.) For example, consider the HyperLink Web
control's NavigateUrl property. The code for this property looks like
so:

public string NavigateUrl
{
  get
  {
    string text = (string) ViewState["NavigateUrl"];
    if (text != null)
       return text;
    else
       return string.Empty;
  }
  set
  {
    ViewState["NavigateUrl"] = value;
  }
}

As this code sample illustrates, whenever a control's property is
read, the control's ViewState is consulted. If there is not an entry
in the ViewState, then the default value for the property is returned.
When the property is assigned, the assigned value is written directly
to the ViewState.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文