各位程序员都好。
我想对一个数据库进行分页,每个数据库由5个项目组成,并使用打开页面的查询。当我单击按钮时,我想更改数据库连接的查询并刷新数据列表,其中包含我所创建的查询(新的5项)的新数据,但不知怎的,我的代码需要一些帮助。我是一名基本的c#程序员,欢迎各种帮助。
ASP
<link rel="stylesheet" href="../Images/book-style.css" />
<link rel="stylesheet" href="../Images/form.css" />
<link rel="stylesheet" href="../Images/style.css" />
<span id="bookshead" />
<div style="margin-top:50px" >
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID_AUTHOR" DataSourceID="SqlDataSource1" SeparatorStyle-Wrap="False">
<ItemTemplate>
<div class="books" style="width:530px;height:150px;margin-bottom:20px;border:1px dotted black;border-radius:5px;box-shadow:2px 2px 6px black;">
<p class="book" runat="server"><%# Eval("TITLE") %></p>
<p class="author"><%# Eval("NAME") %> <%# Eval("SURNAME") %></p>
<img class="book-image" runat="server" alt="book image" src='<%# Eval("imazhi") %>' style="width:85px;height:130px" />
<br />
<div class="addtowishlist" >
<a href="#" >Add to Wishlist</a>
</div>
</div>
</ItemTemplate>
</asp:DataList>
</div>
<asp:Label runat="server" ID="labe" Text="HELLLOO"></asp:Label>
<form id="ff" runat="server" >
<div id="Navigation" class="navigation">
<div id="leftnav">
<asp:Button ID="PreviousPageNav" runat="server" href="#bookshead" OnClick="updateBackward" Text="<< Librat e mëparshëm" />
<asp:Label ID="PagerLocation" runat="server" />
<asp:Button ID="NextPageNav" runat="server" href="#bookshead" OnClick="updateFoward" Text=" Librat e ardhshëm>>"/>
</div>
</div>
</form>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:eLibraryPConnectionString %>" SelectCommand="Select *FROM (AUTHORS a JOIN BOOKS_AUTHORS ba ON a.ID_AUTHOR=ba.ID_AUTHOR) JOIN BOOKS b ON ba.ID_BOOK=b.ID_BOOK WHERE a.ID_AUTHOR>=1 AND a.ID_AUTHOR<=5"></asp:SqlDataSource>
</asp:Content>
和C#
private int firstItem=1;
private int lastItem=5;
public void updateFoward(object o, EventArgs e)
{
firstItem += 5;
lastItem += 5;
SqlDataSource sql = new SqlDataSource();
sql.ID = "SqlDataSource1";
sql.SelectCommand = "Select * FROM (AUTHORS a JOIN BOOKS_AUTHORS ba ON a.ID_AUTHOR=ba.ID_AUTHOR) JOIN BOOKS b ON ba.ID_BOOK=b.ID_BOOK WHERE a.ID_AUTHOR>=" + firstItem + "AND a.ID_AUTHOR<=" + lastItem;
labe.Text =sql.ID;
DataList1.DataBind();
}
public void updateBackward(object o,EventArgs e)
{
firstItem -= 5;
lastItem -= 5;
SqlDataSource sql = new SqlDataSource();
labe.Text = "Backward";
sql.ID = "SqlDataSource1";
sql.SelectCommand = "Select * FROM (AUTHORS a JOIN BOOKS_AUTHORS ba ON a.ID_AUTHOR=ba.ID_AUTHOR) JOIN BOOKS b ON ba.ID_BOOK=b.ID_BOOK WHERE a.ID_AUTHOR>=" + firstItem + "AND a.ID_AUTHOR<=" + lastItem;
DataList1.DataBind();
}
}
答案 0 :(得分:1)
此处要解决的第一个问题是firstitem
和lastitem
变量是在页面的类级别定义的。重要的是要记住,ASP.Net中的每个事件都会产生一个全新的类实例,并运行整个页面生命周期:不仅仅是事件代码本身。来自页面类的先前实例的任何内容都消失了。因此,例如,单击“updateForward”按钮,现有代码将始终将结果从6到10运行,无论您单击它多少次。
这里的快速解决方案是将此数据存储在Session或ViewState中,而不是存储在类中。我将继续使用Session作为例子。
第二个问题是代码如下:
sql.SelectCommand = "Select * FROM (AUTHORS a JOIN BOOKS_AUTHORS ba ON a.ID_AUTHOR=ba.ID_AUTHOR) JOIN BOOKS b ON ba.ID_BOOK=b.ID_BOOK WHERE a.ID_AUTHOR>=" + firstItem + "AND a.ID_AUTHOR<=" + lastItem;
这里实际上有两个问题。第一个很容易纠正:在firstItem
替换之后,单词“AND”之前没有任何间距。第二个问题将需要更多的工作:“包含参数的字符串连接”技术使您对sql注入开放,应该避免。好消息是,此主要安全问题的解决方案也会产生很好的副作用,使您的数据源再次运行。
首先,让我们先看看一些现有的ASP标记:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:eLibraryPConnectionString %>"
SelectCommand="Select * FROM (AUTHORS a JOIN BOOKS_AUTHORS ba ON a.ID_AUTHOR=ba.ID_AUTHOR) JOIN BOOKS b ON ba.ID_BOOK=b.ID_BOOK WHERE a.ID_AUTHOR>=1 AND a.ID_AUTHOR<=5">
</asp:SqlDataSource>
我们想要将标记更改为:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:eLibraryPConnectionString %>"
SelectCommand="Select * FROM (AUTHORS a JOIN BOOKS_AUTHORS ba ON a.ID_AUTHOR=ba.ID_AUTHOR) JOIN BOOKS b ON ba.ID_BOOK=b.ID_BOOK WHERE a.ID_AUTHOR>= @firstItem AND a.ID_AUTHOR<= @lastItem">
<SelectParameters>
<asp:SessionParameter name="firstItem" sessionfield="firstItem" type="Int32" />
<asp:SessionParameter name="lastItem" sessionfield="lastItem" type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
如果您想使用ViewState而不是会话,则可以使用asp:ViewStateParameter。还有asp:QueryStringParameters和其他一些你可以使用的选项。
新标记告诉数据源有关sql字符串中占位符的信息,并告诉它在哪里可以找到这些占位符的数据。数据源将处理将数据填充到字符串本身......或者更确切地说,它不会。以这种方式完成查询参数的好处是参数数据永远直接替换为sql命令,即使在数据库服务器上也是如此,消除了sql注入攻击的可能性。
现在您可以简化updateForward()/ Backward()方法,如下所示:
public void updateFoward(object o, EventArgs e)
{
Session["firstItem"] = (int)Session["firstItem"] + 5;
Session["lastItem"] = (int)Session["lastItem"] + 5;
DataList1.DataBind();
}
udpateBackward()方法需要进行类似的更改。切换为长格式x = x + 5
而不是x += 5
,以便您可以在适当的位置将Object
会话值转换为int
。
您还需要代码来为Session变量设定种子:
public void Page_Load(object o, EventArgs e)
{
if (!IsPostBack)
{
Session["firstItem"] = 1;
Session["lastItem"] = 5;
}
}