C# 与ObjectDataSource搏斗-未定义其他控件和变量

C# 与ObjectDataSource搏斗-未定义其他控件和变量,c#,asp.net,objectdatasource,C#,Asp.net,Objectdatasource,我有一个带有ObjectDataSource的Gridview,有点像这样: <asp:GridView ID="myGridView" runat="server" AllowSorting="True" ondatabound="myGridView_DataBound" cssClass="coolTable" OnRowDataBound="myGridView_RowDataBound" AllowPaging="True" AutoGener

我有一个带有ObjectDataSource的Gridview,有点像这样:

<asp:GridView ID="myGridView" runat="server" AllowSorting="True" ondatabound="myGridView_DataBound" cssClass="coolTable" 
        OnRowDataBound="myGridView_RowDataBound"
         AllowPaging="True" AutoGenerateColumns="False" DataSourceID="myDataSource">
        <PagerSettings mode="NextPreviousFirstLast">
        </PagerSettings>
</asp:GridView>
<asp:ObjectDataSource ID="myDataSource" runat="server"  
         SelectMethod="GetSearchResults" EnablePaging="true"
         StartRowIndexParameterName="startIndex" 
         MaximumRowsParameterName="pageSize"
         SortParameterName="sortBy" SelectCountMethod="GetSearchCount" >   
</asp:ObjectDataSource>
浏览了链接到那里的页面生命周期概述,但仍然不理解为什么我的其他变量不可用

但这是我真正的问题——我真的不在乎为什么它们不可用;我想知道一个好的模式,使我的GetSearchResults函数可以使用(在页面加载期间设置的)值。目前我正在会议中保存东西,但这似乎有点荒谬

[编辑以添加背景] 我正在对Page_Load进行一些数据库查询,以设置一些值,这些值反过来会影响页面的布局和内容。这些值还用于修改my GridView中数据的选择条件。我开始使用ObjectDataSource,是因为它允许我高效地分页浏览大量记录(),但最初我不知道创建了一个新的页面实例,然后调用了该方法——我认为这是像回发一样处理的。我希望避免将这些临时值保存在表单字段、会话变量等中。看起来唯一的方法可能是在正常页面生命周期中填充Gridview,但这意味着放弃Gridview的自动分页。

Andy指出了为什么页面元素在SelectMethod中不可用,以下是MSDN的解释:

如果是实例方法,则创建业务对象并 每次使用SelectMethod指定的方法时都会被销毁 属性被称为

但是,在我的试验中,我可以通过当前上下文的Request.Forms集合访问页面变量。这有点令人困惑。但如果您定义了一些html表单元素,则可以在SelectMethod by Request.Forms集合中访问它们。您还可以访问服务器变量的值,但是,如果深入研究,您可以看到它们的名称取决于页面控制树中的层次结构

这是我的试用版,在我的aspx文件中:

<input name="txtCriteria"></input>
<asp:Button  runat="server" ID="btnPostSearch" OnClick="btnPostSearch_Click"/>

<asp:GridView ID="myGridView" runat="server" AllowSorting="True"
     AllowPaging="True" AutoGenerateColumns="False" DataSourceID="myDataSource">
    <Columns>
        <asp:BoundField DataField="Result" />
    </Columns>
    <PagerSettings mode="NextPreviousFirstLast">
    </PagerSettings>
</asp:GridView>
<asp:ObjectDataSource ID="myDataSource" runat="server" TypeName="" 
    SelectMethod="GetSearchResults">   
</asp:ObjectDataSource>

这是代码隐藏文件:

public List<SearchResult> GetSearchResults()
{
    string criteria = string.Empty;
    if (HttpContext.Current.Request["txtCriteria"] != null)
    {
        criteria = HttpContext.Current.Request["txtCriteria"];
    }

    List<SearchResult> searchResults = new List<SearchResult>();
    searchResults.Add(new SearchResult() { Result = "trial 1 " + criteria });
    searchResults.Add(new SearchResult() { Result = "trial 2 " + criteria });

    return searchResults;
}

protected void btnPostSearch_Click(object sender, EventArgs e)
{
    myGridView.DataBind();
}
public List GetSearchResults()
{
字符串条件=string.Empty;
if(HttpContext.Current.Request[“txtCriteria”]!=null)
{
criteria=HttpContext.Current.Request[“txtCriteria”];
}
列表搜索结果=新列表();
添加(新的SearchResult(){Result=“trial 1”+criteria});
添加(新的SearchResult(){Result=“试用2”+标准});
返回搜索结果;
}
受保护的无效btnPostSearch\u单击(对象发送者,事件参数e)
{
myGridView.DataBind();
}
Andy指出了页面元素在SelectMethod中不可用的原因,下面是MSDN的解释:

如果是实例方法,则创建业务对象并 每次使用SelectMethod指定的方法时都会被销毁 属性被称为

但是,在我的试验中,我可以通过当前上下文的Request.Forms集合访问页面变量。这有点令人困惑。但如果您定义了一些html表单元素,则可以在SelectMethod by Request.Forms集合中访问它们。您还可以访问服务器变量的值,但是,如果深入研究,您可以看到它们的名称取决于页面控制树中的层次结构

这是我的试用版,在我的aspx文件中:

<input name="txtCriteria"></input>
<asp:Button  runat="server" ID="btnPostSearch" OnClick="btnPostSearch_Click"/>

<asp:GridView ID="myGridView" runat="server" AllowSorting="True"
     AllowPaging="True" AutoGenerateColumns="False" DataSourceID="myDataSource">
    <Columns>
        <asp:BoundField DataField="Result" />
    </Columns>
    <PagerSettings mode="NextPreviousFirstLast">
    </PagerSettings>
</asp:GridView>
<asp:ObjectDataSource ID="myDataSource" runat="server" TypeName="" 
    SelectMethod="GetSearchResults">   
</asp:ObjectDataSource>

这是代码隐藏文件:

public List<SearchResult> GetSearchResults()
{
    string criteria = string.Empty;
    if (HttpContext.Current.Request["txtCriteria"] != null)
    {
        criteria = HttpContext.Current.Request["txtCriteria"];
    }

    List<SearchResult> searchResults = new List<SearchResult>();
    searchResults.Add(new SearchResult() { Result = "trial 1 " + criteria });
    searchResults.Add(new SearchResult() { Result = "trial 2 " + criteria });

    return searchResults;
}

protected void btnPostSearch_Click(object sender, EventArgs e)
{
    myGridView.DataBind();
}
public List GetSearchResults()
{
字符串条件=string.Empty;
if(HttpContext.Current.Request[“txtCriteria”]!=null)
{
criteria=HttpContext.Current.Request[“txtCriteria”];
}
列表搜索结果=新列表();
添加(新的SearchResult(){Result=“trial 1”+criteria});
添加(新的SearchResult(){Result=“试用2”+标准});
返回搜索结果;
}
受保护的无效btnPostSearch\u单击(对象发送者,事件参数e)
{
myGridView.DataBind();
}

当您开始使用ASP.NET的DataSourceControl(ObjectDataSource、SqlDataSource、AccessDataSource等)及其对应的DataboundControl(DropDownList、DetailsView、ListView、FormView、GridView)时,您真的想忘记ASP.NET的生命周期(并停止拉扯头发),如果您做得好,您甚至可以忘记代码隐藏代码(aspx.cs文件),因为现在系统可以在数据源和数据绑定控件之间非常自动

事实上,这种范式(仅从.NET2.0开始出现)确实有助于关注类似HTML的声明性代码

DataSourceControl使用类型为的对象集合作为其使用的方法的参数。例如,ObjectDataSource的SelectMethod使用(ParameterCollection类型的)属性

您可以声明性地定义这些参数。让我们举一个例子:

<form id="form1" runat="server">
<div>
    <asp:TextBox ID="MyTextBox" Text="3" runat="server" />
    <asp:Button runat="server" Text="Run" />

    <asp:GridView ID="myGridView" runat="server" DataSourceID="myDataSource" />
    <asp:ObjectDataSource ID="myDataSource" runat="server" 
             SelectMethod="GetSearchResults"
             TypeName="WebApplication1.Code.MyModel">
        <SelectParameters>
            <asp:ControlParameter ControlID="MyTextBox" PropertyName="Text" Name="myCount" />
        </SelectParameters>
    </asp:ObjectDataSource>
</div>
</form>
如您所见,该方法还定义了一个
myCount
参数(它区分大小写,是的,ASP.NET将自动从
string
转换为
int
,这几乎是神奇的,它在引擎盖下使用类型转换器),因此一切都将按预期工作,没有任何代码隐藏。它是一种MV模式(M model V view),由DataSourceControl/DataBoundControl进行绑定

所以,你现在必须这样想,并使用参数。如果提供的参数列表(QueryString、Cookie、表单、概要文件、路由、会话)不够,您可以提供自己的参数列表。例如,我可以定义一个特殊参数,随机获取myCount(这只是一个示例:-):

我可以这样使用它,我可以为这个参数定义自定义参数:

<%@ Register Namespace="WebApplication1.Code" TagPrefix="my" Assembly="WebApplication1" %>
...
<SelectParameters>
    <my:RandomParameter Name="myCount" Min="10" Max="20" />
</SelectParameters>

当您开始使用ASP.NET的DataSourceControl(ObjectDataSource、SqlDataSource、AccessDataSource等)及其对应的DataboundControl(DropDownList、DetailsView、ListView、FormView、GridView)时,您真的想忘记ASP.NET的生命周期(并停止拉扯头发),如果您做得好,甚至可以忘记代码b