我有一个asp转发器,它为每个条目设置一个generichandler(.ashx)参数。这用于创建由用户发布的评论,并通过从数据库中提取用户帖子的头像来显示该用户的帖子。如果只有一个帖子,它可以正常工作,但只要有两个或更多帖子,我就会在“get.Open()”(下面提供的代码)中的“GetIdFromUserName”方法中遇到“连接”没有关闭,连接当前状态是打开的“。请记住,只有当存在多个注释时才会发生这种情况,我不知道是什么导致这种情况。
我发现了一件事:如果我让asp:image对象不使用“Eval”(所以它只为每个帖子显示相同的图像而不管它)是否有效,但除此之外我不知道。如果只显示一个帖子,Eval确实可以正常工作,如前所述。
如果有人知道如何解决这个问题,我将非常感激。
ASP代码:
<asp:Repeater ID="CommentsRepeater" runat="server" OnItemDataBound="CommentsRepeater_ItemDataBound">
<ItemTemplate>
<div class="comment">
<div class="commentInfo">
<strong>
<asp:Image ID="Avatar" ImageUrl='<%# "CommentsAvatarHandler.ashx?id=" + Eval("UserName") %>' runat="server" Height="100px" Width="100" />
<asp:LinkButton ID="CommentName" Text='<%# Eval("UserName") %>' CommandArgument='<%# Eval("UserId") %>' CausesValidation="false" runat="server"></asp:LinkButton></strong> @
<asp:Label ID="CommentDate" Text='<%# Eval("PostedDate") %>' runat="server"></asp:Label>
<div class="commentVote">
<asp:LinkButton ID="VoteUp" CommandArgument='<%# Eval("CommentId") %>' OnClick="VoteUpClick" CausesValidation="false" runat="server"><img src="images/pluss2.png" /></asp:LinkButton>
<asp:LinkButton ID="VoteDown" CommandArgument='<%# Eval("CommentId") %>' OnClick="VoteDownClick" CausesValidation="false" runat="server"><img src="images/minus2.png" /></asp:LinkButton>
<strong>(<asp:Label ID="CommentVote" Text='<%# Eval("Vote") %>' runat="server"></asp:Label>)</strong>
</div>
</div>
<div class="commentText">
<asp:Label ID="CommentText" Text='<%# Eval("Comment") %>' runat="server"></asp:Label>
</div>
</div>
</ItemTemplate>
<SeparatorTemplate>
<br />
</SeparatorTemplate>
</asp:Repeater>
相关位:
<asp:Image ID="Avatar" ImageUrl='<%# "CommentsAvatarHandler.ashx?id=" + Eval("UserName") %>' runat="server" Height="100px" Width="100" />
这是处理程序:
public class CommentsAvatarHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
String userName = context.Request.QueryString["id"];
Gamez.Sql.GetAvatarOfUser(context, userName);
}
public bool IsReusable
{
get
{
return false;
}
}
}
处理程序使用的方法:
public static void GetAvatarOfUser(HttpContext context, String userName)
{
SqlDataReader reader;
try
{
Guid id = GetIdFromUserName(userName);
command.CommandText = "SELECT Avatar FROM UserAttributes WHERE UserId = @id";
command.Parameters.AddWithValue("@id", id);
connection.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
try
{
context.Response.ContentType = "image/jpg";
context.Response.BinaryWrite((byte[])reader["Avatar"]);
}
catch { }
}
if (reader != null)
reader.Close();
}
finally
{
if (connection != null)
{
connection.Close();
}
}
}
GetIdFromUserName方法:
public static Guid GetIdFromUserName(String name)
{
command.Parameters.Clear();
command.CommandText = "SELECT UserId FROM aspnet_Users WHERE UserName = @UserName";
command.Parameters.AddWithValue("@UserName", name);
connection.Open(); // <---- DESCRIBED CRASH HAPPENS HERE
Guid id = (Guid)command.ExecuteScalar();
connection.Close();
return id;
}
GetAvatarFromUser和GetIdFromUserName位于同一个库中,可以访问相同的SQLCommand(命令)和SQLConnection(连接)对象。
答案 0 :(得分:2)
在您的代码中,您似乎为每个请求使用了connection
和command
的相同实例。我假设这两个都是页面级变量?
为 每个 sql请求创建这两个变量的单独实例。
此外,您应该将Connection和Command初始化包装在using块中。这将负责正确关闭和处理这两种资源并使用最佳实践。像这样:
using (SqlConnection conn = [CONNECTION INITIALIZATION])
{
using (SqlCommand command = new SqlCommand(conn))
{
...
using (SqlDataReader reader = command.ExecuteReader())
{
.....
}
}
}
目前,你设置它的方式,你要求麻烦。
修改强>
当您有第二篇帖子时,您的代码会失败,因为您正在跨多个请求共享您的连接对象。因此,当检索到第一个帖子的信息(打开连接)时,您正试图检索另一个帖子(再次尝试打开 相同的 连接)。
这有意义吗?