从Request.Form读取值

时间:2013-10-11 14:03:21

标签: c# asp.net custom-controls single-page-application

过去开发动态加载多控制单页类型应用程序时,我遇到了很多关于viewstate的问题。原因是必须在 OnInit 阶段添加控件,而不是之后。由于我正在处理一个控件事件(例如,dropdownlist上的selectedIndexChanged),我在事件处理程序阶段加载它们。我知道儿童控制页面循环追赶,但我注意到有时它只是不起作用。

我再一次负责开发这样的应用程序。这次我决定采取不同的方法。对于那些根据其值加载动态控件的选择控件,我将在OnInit阶段检查它们的回发响应值(来自Request.Form)并立即加载控件。我不会从事件处理程序阶段加载任何动态控件,因为这是在OnPreRender之前,而且为时已晚。

总结:
在页面周期的早期(例如OnInit)从Request.Form集合中检查控件的值然后执行操作,而不是在页面循环的后期检查实际控件的值会有什么陷阱?

1 个答案:

答案 0 :(得分:0)

其中一个陷阱是,如果<form>中没有包含控件,则它将不存在。我建议继续在事件处理程序阶段添加它们 - 因为那时你知道要添加什么 - 但是存储必要的信息以重构ViewStateSessionState中的那些控件。

通过这样做,您将能够在OnInit中重新创建它们,但不必处理您现在所处的道路周围的其他一些复杂问题。

所以,假设您发现需要构建控件。你要建造它:

var tb = new TextBox();
tb.ID = "myTextBox";
...

但您还要保存必要的状态信息:

this.ViewState.StoreControl(typeof(TextBox), "myTextBox");

然后只构建扩展方法:

public static void StoreControl(this StateBag vs, Type controlType, string name)
{
    var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
    if (dynamicControls == null)
    {
        dynamicControls = new List<Tuple<Type, string>>();
        vs["DynamicControls"] = dynamicControls;
    }

    var t = dynamicControls.FirstOrDefault(tp => tp.Item2 == name);
    if (t == null) { dynamicControls.Add(Tuple.Create(controlType, name)); }
}

然后在OnInit你可能会做这样的事情:

var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
if (dynamicControls != null)
{
    foreach (var tp in dynamicControls)
    {
        Control c = Activator.CreateInstance(tp.Item1) as Control;
        c.ID = tp.Item2;
        this.Controls.Add(c);
    }
}

注意:此代码是在SO上编写的。它没有被编译或调试。但是你明白了。