在页面生命周期的哪个位置可以安全地加载/删除动态控件?

发布于 2024-09-28 16:55:45 字数 1163 浏览 5 评论 0原文

我正在 ASP.NET 中处理动态字段,因为最终用户的要求非常具体且严格,仅解释一下就需要 2 个小时。我只想说,我不能让这个要求消失。

不管怎样,我已经有了一个可行的解决方案;控件加载、渲染或维护其 ViewState 没有问题。这就是我的 OnLoad 的样子:

public void override OnLoad(EventArgs e){
    //don't need to check IsPostback, we have to load the controls on every POST    
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
}

为了实现一些需要、禁用或可选动态字段的业务逻辑,我需要获取动态控件的发布值(即 ViewState),然后才能将它们实际添加到页面控制层次结构。

我想这是一个先有鸡还是先有蛋的问题。 ASP.NET 不会自动将 ViewState 与正确的动态控件关联起来,直到我将它们全部添加到页面中。另一方面,在我的服务层应用了取决于其当前值的业务规则之前,我无法将这些控件添加到页面中。我试图通过编写这段伪代码来解决这个相当令人不快的问题:

public void override OnLoad(EventArgs e){
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
 if (IsPostBack){
  PushControlValuesIntoForm(initialFormDefinition);
  var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
  ReBuildControls(updatedFormDefinition); //remove controls and re-add them
 }
}

不幸的是,当您清除控件并重新添加它时,即使控件类型和 ControlID 完全相同,ViewState 也会丢失,所以这解决方案是半身像。欢迎任何关于如何实现我所追求的合理想法!

I'm working with dynamic fields in ASP.NET due to a very specifc and rigid end-user requirement that would take 2 hours just to explain. Suffice it to say, I can't make the requirement go away.

Anyway, I have a working solution in place; no problems with controls loading, rendering or maintaining their ViewState. This is what my OnLoad looks like:

public void override OnLoad(EventArgs e){
    //don't need to check IsPostback, we have to load the controls on every POST    
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
}

In order to implement some biz logic around which dynamic fields are required, disabled or optional, I need to get the posted values (i.e. the ViewState) of my dynamic controls before I can actually add them to the page control hierarchy.

It's sort of a chicken/egg problem I suppose. ASP.NET won't automagically associate ViewState with the proper dynamic control until I've added them all to the page. On the other hand, I can't add these controls to the page until my service layer has applied biz rules that hinge on their current values. I tried to get around this rather unpleasant problem by writing this bit of pseudo-code :

public void override OnLoad(EventArgs e){
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
 if (IsPostBack){
  PushControlValuesIntoForm(initialFormDefinition);
  var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
  ReBuildControls(updatedFormDefinition); //remove controls and re-add them
 }
}

Unfortunately, when you clear a control and re-add it, the ViewState is lost, even if the control type and ControlID are exactly the same, so this solution is a bust. Any reasonable ideas on how to accomplish what I'm after are welcome!

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

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

发布评论

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

评论(1

甜`诱少女 2024-10-05 16:55:45

一种方法可能是加载控件,然后决定是否需要更新表单定义,如果是,则再次重新启动页面生命周期。请参阅下面的示例代码:

public void override OnLoad(EventArgs e){

 var updatedFormDef = Context.Items["UpdatedDef"] as FormDefinition;
 if (null != updatedFormDef)
 {
    // Updated form def, rebuild controls
    BuildControls(updatedFormDef);
 } 
 else
 {
    // load initial form def
    var initialFormDefinition = ServiceLayer.GetFormDefinition(id);
    BuildControls(initialFormDefinition);
    // check whether we need to update form def
    if (IsPostBack){
       PushControlValuesIntoForm(initialFormDefinition);
       var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
       if (null != updatedFormDefinition)
       {
          // we have to update UI, transfer to self
          Context.Items["UpdatedDef"] = updatedFormDefinition;
          try
          {
              Server.Transfer(this.Request.RawUrl, true);
          }
          catch(ThreadAbortException)
          {
             // Do nothing
          }
       }
 }
}

One way could be to load your controls and then decide if you need form definition to be be updated and if yes then re-initiate page life cycle again. See the below sample code:

public void override OnLoad(EventArgs e){

 var updatedFormDef = Context.Items["UpdatedDef"] as FormDefinition;
 if (null != updatedFormDef)
 {
    // Updated form def, rebuild controls
    BuildControls(updatedFormDef);
 } 
 else
 {
    // load initial form def
    var initialFormDefinition = ServiceLayer.GetFormDefinition(id);
    BuildControls(initialFormDefinition);
    // check whether we need to update form def
    if (IsPostBack){
       PushControlValuesIntoForm(initialFormDefinition);
       var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
       if (null != updatedFormDefinition)
       {
          // we have to update UI, transfer to self
          Context.Items["UpdatedDef"] = updatedFormDefinition;
          try
          {
              Server.Transfer(this.Request.RawUrl, true);
          }
          catch(ThreadAbortException)
          {
             // Do nothing
          }
       }
 }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文