我正在使用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),然后才能将它们实际添加到页面控件层次结构中。
我想这是一种鸡/蛋的问题。在将View全部添加到页面之前,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也会丢失,所以这个解决方案就是破解。关于如何完成我所追求的任何合理的想法都是受欢迎的!
答案 0 :(得分:1)
一种方法是加载您的控件,然后决定是否需要更新表单定义,如果是,则再次重新启动页面生命周期。请参阅以下示例代码:
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
}
}
}
}