asp:转发器w / asp:image和generic-handler - SQLConnection崩溃

时间:2013-04-24 15:09:08

标签: asp.net sql image repeater generic-handler

我有一个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(连接)对象。

1 个答案:

答案 0 :(得分:2)

在您的代码中,您似乎为每个请求使用了connectioncommand的相同实例。我假设这两个都是页面级变量?

每个 sql请求创建这两个变量的单独实例。

此外,您应该将Connection和Command初始化包装在using块中。这将负责正确关闭和处理这两种资源并使用最佳实践。像这样:

using (SqlConnection conn = [CONNECTION INITIALIZATION])
   {
   using (SqlCommand command = new SqlCommand(conn))
      {
      ...
         using (SqlDataReader reader = command.ExecuteReader())
         {
            .....
         }
      }
   }

目前,你设置它的方式,你要求麻烦。

修改

当您有第二篇帖子时,您的代码会失败,因为您正在跨多个请求共享您的连接对象。因此,当检索到第一个帖子的信息(打开连接)时,您正试图检索另一个帖子(再次尝试打开 相同的 连接)。

这有意义吗?