1

我有一个 asp 中继器,它为每个条目设置不同的 generichandler (.ashx) 参数。这用于创建用户发布的评论,并通过从数据库中获取用户发布的头像来显示该用户的头像。如果只有一个帖子,它可以正常工作,但是一旦有两个或更多帖子,我就会在“connection.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(连接)对象。

4

1 回答 1

2

从您的代码看来,您对每个请求都使用了相同的connection实例command。我假设这两个都是页面级变量?

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

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

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

目前,按照您的设置方式,您正在自找麻烦。

编辑

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

那有意义吗?

于 2013-04-24T17:31:09.923 回答