我有一个带有ObjectDataSource的Gridview,有点像这样:
angular.isDate(myDate);
Andy我的函数GetSearchResults被调用,所以这一切都很好。问题是在GetSearchResults中,我想使用除传递给它之外的其他变量,但是当GetSearchResults运行时它们似乎没有值。我在调试器中进行了操作,我可以看到在GetSearchResults之前调用了Page_Load - 但引用我页面上的任何控件都会引发错误,属于我页面的字段没有值(即使我在Page_Load中设置它们)。
我阅读ASP.Net Object Data Source - Data Binding并浏览了链接到那里的Page Life Cycle Overview,但仍然不明白为什么我的其他变量不可用。
但这是我真正的问题 - 我真的不在乎为什么他们不可用;我想知道一个好的模式,使值可用(在Page_Load期间设置)到我的GetSearchResults函数。目前我正在节约会议,但这似乎有点荒谬。
[编辑添加背景] 我正在对Page_Load进行一些数据库查询,以设置一些值,这些值又会影响我的页面的布局和内容。这些值还用于修改GridView中数据的选择标准。我开始使用ObjectDataSource,因为允许我有效地浏览大量的记录(https://msdn.microsoft.com/en-us/library/bb445504.aspx),但最初并没有理解创建了一个新的Page实例,之后调用了该方法 - 我在想它处理就像回发一样。我希望避免在表单字段,会话变量等中保存这些临时值。看起来这样做的唯一方法是在正常的页面生命周期中填充Gridview,但看起来这意味着放弃自动分页Gridview。
答案 0 :(得分:0)
In this question Andy指出为什么页面元素在SelectMethod中不可用,这是MSDN的解释:
如果是实例方法,则创建业务对象 每次SelectMethod指定的方法都会销毁 财产被称为。
但是,在我的试验中,我可以通过当前上下文的Request.Forms集合访问页面变量。这有点令人困惑。但是,如果您定义了一些html表单元素,则可以通过Request.Forms集合在SelectMethod中访问它们。您也可以访问服务器变量的值,但是,如果您深入了解它,您可以看到它们的名称取决于页面控制树中的层次结构。
这是我的试用版,在我的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();
}
答案 1 :(得分:0)
当你开始使用ASP.NET的DataSourceControls(ObjectDataSource,SqlDataSource,AccessDataSource等)及其对应的DataBoundControls(DropDownList,DetailsView,ListView,FormView,GridView)时,你真的想忘记ASP.NET生命周期(并停止拉头发,如果你做得好,你甚至可以忘记代码隐藏代码(aspx.cs文件),因为现在系统在数据源和数据绑定控件之间可以非常自动。
事实上,这个范例(仅从.NET 2.0开始)确实有助于专注于类似于声明的HTML代码。
DataSourceControl使用类型为Parameter的对象集合作为其使用的方法的参数。例如,ObjectDataSource的SelectMethod使用SelectParameters属性(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>
在这里,myDataSource将GetSearchResults
定义为某个类中SelectMethod
类的MyModel
(我已经省略了其他参数,但想法是相同的)。它还定义了一个名为myCount
的参数。此参数是ControlParameter(还有其他参数):它将连接到ASP.NET控件MyTextBox
,它恰好被定义为TextBox控件,并将使用TextBox的Text
属性作为myCount
参数的值。
以下是对象模型的代码:
namespace WebApplication1.Code
{
public class MyModel
{
public string Name { get; set; }
public static IEnumerable GetSearchResults(int myCount)
{
for (int i = 0; i < myCount; i++)
{
yield return new MyModel { Name = "item " + i };
}
}
}
}
如您所见,该方法还定义了myCount
参数(区分大小写,是的,ASP.NET会自动从string
转换为int
,这几乎是魔术,它使用引擎盖下的TypeConverters),因此一切都将按预期工作,没有任何代码隐藏代码。它是某种MV模式(M模型V视图)和DataSourceControl / DataBoundControl进行绑定。
所以,你现在必须这样想,并使用参数。如果提供的参数列表(QueryString,Cookie,Form,Profile,Route,Session)不够,您可以提供自己的参数。例如,我可以定义一个随机获取myCount的特殊参数(这只是一个例子: - ):
我可以像这样使用它,我可以为这个参数定义自定义参数:
<%@ Register Namespace="WebApplication1.Code" TagPrefix="my" Assembly="WebApplication1" %>
...
<SelectParameters>
<my:RandomParameter Name="myCount" Min="10" Max="20" />
</SelectParameters>
自定义参数类型代码:
public class RandomParameter : Parameter
{
protected override object Evaluate(HttpContext context, Control control)
{
// you can get to page or environment from here with 'context' and 'control' parameters
return new Random(Environment.TickCount).Next(Min, Max);
}
[DefaultValue(1)]
public int Min
{
get
{
object o = ViewState["Min"];
return o is int ? (int)o : 1;
}
set
{
if (Min != value)
{
ViewState["Min"] = value;
OnParameterChanged();
}
}
}
[DefaultValue(10)]
public int Max
{
get
{
object o = ViewState["Max"];
return o is int ? (int)o : 10;
}
set
{
if (Max != value)
{
ViewState["Max"] = value;
OnParameterChanged();
}
}
}
}