asp.net 线程评论?

发布于 2024-09-24 08:17:16 字数 5506 浏览 5 评论 0原文

我正在致力于在 ASP.net 4.0 和 sql server 2008 中创建一个博客,并且想了解如何创建线程评论系统。通过线程我的意思是每个评论都会有一个回复链接,并且评论会在其回复的评论下方缩进。因此,您可以回复文章本身或回复任何评论。

这在论坛和博客上很常见,但我找不到任何文章可以解释并显示如何完成此操作的代码示例。

以下是我创建的内容,但它仅适用于一层深度。我想让它递归,这样深度就没有限制:。我该怎么做?任何建议、带有代码示例的文章都会很棒!

评论数据库表

commentId
parentId
postId
date
author
authorEmail
authorURL
authorIP
content
IsApproved

ASP.NET 标记:

<asp:ListView ID="ListView1" runat="server" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
    <div class="commentwrap">
        <div class="commentsTitleArea">
            <span class="commentCounter"><%# Convert.ToInt32(Container.DisplayIndex) + 1%>. </span>&nbsp;&nbsp;<img src="../images/decoy-icon-16px.png" alt="Comment by..." title="Comment by..." class="blogCommentIcon" /><a href='<%# Eval("AuthorUrl")%>' target="_blank" rel="nofollow"><%# " " + Eval("Author")%></a>&nbsp;&nbsp;<%# Eval("Date")%></div>
        <div class="commentText">
            <%# Eval("Content") %>
            <div><span class="btnCommentReply"><a href='<%# "article.aspx?article=" + Request.QueryString["article"] + "&amp;cid=" + Eval("commentId") + "#comment" %>'>REPLY</a></span></div>
        </div>
        <asp:ListView ID="ListView2" runat="server">
            <ItemTemplate>
                <div class="commentwrap commentNest">
                    <div class="commentsTitleArea">
                        <span class="commentCounter"><%# Convert.ToInt32(Container.DisplayIndex) + 1%>. </span>&nbsp;&nbsp;<img src="../images/decoy-icon-16px.png" alt="Comment by..." title="Comment by..." class="blogCommentIcon" /><a href='<%# Eval("AuthorUrl")%>' target="_blank" rel="nofollow"><%# " " + Eval("Author")%></a>&nbsp;&nbsp;<%# Eval("Date")%></div>
                    <div class="commentText">
                        <%# Eval("Content") %>
                    </div>
                </div>
            </ItemTemplate>
            <EmptyDataTemplate>
            </EmptyDataTemplate>
            <LayoutTemplate>
                <div id="itemPlaceholderContainer" runat="server">
                    <span id="itemPlaceholder" runat="server" />
                </div>
            </LayoutTemplate>
        </asp:ListView>
    </div>
</ItemTemplate>
<EmptyDataTemplate>
</EmptyDataTemplate>
<LayoutTemplate>
    <div id="itemPlaceholderContainer" runat="server">
        <span id="itemPlaceholder" runat="server" />
    </div>
    <div class="dataPagerWrap">
        <asp:DataPager ID="ListViewpager" runat="server" PagedControlID="ListView1" PageSize="30" QueryStringField="page">
            <Fields>
                <asp:NextPreviousPagerField ShowFirstPageButton="True" ShowNextPageButton="False" ShowPreviousPageButton="False" FirstPageText="«" ButtonCssClass="dataPagerBackForward" />
                <asp:NumericPagerField ButtonCount="8" CurrentPageLabelCssClass="dataPagerCurrent" NumericButtonCssClass="dataPager" PreviousPageText="..." NextPageText="..." NextPreviousButtonCssClass="dataPagerBackForward" />
                <asp:NextPreviousPagerField ShowLastPageButton="True" ShowNextPageButton="False" ShowPreviousPageButton="False" LastPageText="»" ButtonCssClass="dataPagerBackForward" />
            </Fields>
        </asp:DataPager>
    </div>
    <div class="padding"></div>
</LayoutTemplate>


    ALTER PROCEDURE [dbo].[sp_blog_GetComments]
(
    @article int
)
AS
    SET NOCOUNT ON;

    SELECT 
    post_Comments.Author, 
    post_Comments.AuthorEmail, 
    post_Comments.AuthorUrl, 
    post_Comments.Content, 
    post_Comments.Date, 
    post_Comments.commentId 
    FROM post_Comments 
    INNER JOIN 
    posts 
    ON post_Comments.postId = posts.postId 
    WHERE(post_Comments.postId = @article) 
    AND (post_Comments.IsApproved = 1) 
    AND (post_Comments.ParentId IS NULL) 
    AND (posts.IsPublished = 1) 
    AND (posts.PublishOnDate <= GETDATE())

    SELECT 
    Author, 
    AuthorEmail, 
    AuthorUrl, 
    Content, 
    Date, 
    ParentId
    FROM post_Comments
    WHERE (postId = @article) 
    AND (IsApproved = 1)

存储过程:

ALTER PROCEDURE [dbo].[Sp_blog_getcomments] (@article INT)
AS
    SET nocount ON;

    SELECT post_comments.author,
           post_comments.authoremail,
           post_comments.authorurl,
           post_comments.content,
           post_comments.date,
           post_comments.commentid
    FROM   post_comments
           INNER JOIN posts
                   ON post_comments.postid = posts.postid
    WHERE ( post_comments.postid = @article )
          AND ( post_comments.isapproved = 1 )
          AND ( post_comments.parentid IS NULL )
          AND ( posts.ispublished = 1 )
          AND ( posts.publishondate <= Getdate() )

    SELECT author,
           authoremail,
           authorurl,
           content,
           date,
           parentid
    FROM   post_comments
    WHERE  ( postid = @article )
           AND ( isapproved = 1 ) 

I am working on creating a blog in ASP.net 4.0 and sql server 2008 and would like to learn how to create a threaded comments system. By threaded I mean each comment would have a reply link and the comments are indented under the comment that it is a reply to. So, you can either respond to the article itself or reply to any of the comments.

This is very common on forums and blogs but I cannot find any articles that would explain and show code example on how this is done.

The following is what I have created but it only works one level of depth. I'd like to make it recursive so there is no limit to the level of depth:. How can I do this? Any advice, articles with code samples would be awesome!

Comments db Table

commentId
parentId
postId
date
author
authorEmail
authorURL
authorIP
content
IsApproved

ASP.NET Markup:

<asp:ListView ID="ListView1" runat="server" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
    <div class="commentwrap">
        <div class="commentsTitleArea">
            <span class="commentCounter"><%# Convert.ToInt32(Container.DisplayIndex) + 1%>. </span>  <img src="../images/decoy-icon-16px.png" alt="Comment by..." title="Comment by..." class="blogCommentIcon" /><a href='<%# Eval("AuthorUrl")%>' target="_blank" rel="nofollow"><%# " " + Eval("Author")%></a>  <%# Eval("Date")%></div>
        <div class="commentText">
            <%# Eval("Content") %>
            <div><span class="btnCommentReply"><a href='<%# "article.aspx?article=" + Request.QueryString["article"] + "&cid=" + Eval("commentId") + "#comment" %>'>REPLY</a></span></div>
        </div>
        <asp:ListView ID="ListView2" runat="server">
            <ItemTemplate>
                <div class="commentwrap commentNest">
                    <div class="commentsTitleArea">
                        <span class="commentCounter"><%# Convert.ToInt32(Container.DisplayIndex) + 1%>. </span>  <img src="../images/decoy-icon-16px.png" alt="Comment by..." title="Comment by..." class="blogCommentIcon" /><a href='<%# Eval("AuthorUrl")%>' target="_blank" rel="nofollow"><%# " " + Eval("Author")%></a>  <%# Eval("Date")%></div>
                    <div class="commentText">
                        <%# Eval("Content") %>
                    </div>
                </div>
            </ItemTemplate>
            <EmptyDataTemplate>
            </EmptyDataTemplate>
            <LayoutTemplate>
                <div id="itemPlaceholderContainer" runat="server">
                    <span id="itemPlaceholder" runat="server" />
                </div>
            </LayoutTemplate>
        </asp:ListView>
    </div>
</ItemTemplate>
<EmptyDataTemplate>
</EmptyDataTemplate>
<LayoutTemplate>
    <div id="itemPlaceholderContainer" runat="server">
        <span id="itemPlaceholder" runat="server" />
    </div>
    <div class="dataPagerWrap">
        <asp:DataPager ID="ListViewpager" runat="server" PagedControlID="ListView1" PageSize="30" QueryStringField="page">
            <Fields>
                <asp:NextPreviousPagerField ShowFirstPageButton="True" ShowNextPageButton="False" ShowPreviousPageButton="False" FirstPageText="«" ButtonCssClass="dataPagerBackForward" />
                <asp:NumericPagerField ButtonCount="8" CurrentPageLabelCssClass="dataPagerCurrent" NumericButtonCssClass="dataPager" PreviousPageText="..." NextPageText="..." NextPreviousButtonCssClass="dataPagerBackForward" />
                <asp:NextPreviousPagerField ShowLastPageButton="True" ShowNextPageButton="False" ShowPreviousPageButton="False" LastPageText="»" ButtonCssClass="dataPagerBackForward" />
            </Fields>
        </asp:DataPager>
    </div>
    <div class="padding"></div>
</LayoutTemplate>


    ALTER PROCEDURE [dbo].[sp_blog_GetComments]
(
    @article int
)
AS
    SET NOCOUNT ON;

    SELECT 
    post_Comments.Author, 
    post_Comments.AuthorEmail, 
    post_Comments.AuthorUrl, 
    post_Comments.Content, 
    post_Comments.Date, 
    post_Comments.commentId 
    FROM post_Comments 
    INNER JOIN 
    posts 
    ON post_Comments.postId = posts.postId 
    WHERE(post_Comments.postId = @article) 
    AND (post_Comments.IsApproved = 1) 
    AND (post_Comments.ParentId IS NULL) 
    AND (posts.IsPublished = 1) 
    AND (posts.PublishOnDate <= GETDATE())

    SELECT 
    Author, 
    AuthorEmail, 
    AuthorUrl, 
    Content, 
    Date, 
    ParentId
    FROM post_Comments
    WHERE (postId = @article) 
    AND (IsApproved = 1)

Stored Procedure:

ALTER PROCEDURE [dbo].[Sp_blog_getcomments] (@article INT)
AS
    SET nocount ON;

    SELECT post_comments.author,
           post_comments.authoremail,
           post_comments.authorurl,
           post_comments.content,
           post_comments.date,
           post_comments.commentid
    FROM   post_comments
           INNER JOIN posts
                   ON post_comments.postid = posts.postid
    WHERE ( post_comments.postid = @article )
          AND ( post_comments.isapproved = 1 )
          AND ( post_comments.parentid IS NULL )
          AND ( posts.ispublished = 1 )
          AND ( posts.publishondate <= Getdate() )

    SELECT author,
           authoremail,
           authorurl,
           content,
           date,
           parentid
    FROM   post_comments
    WHERE  ( postid = @article )
           AND ( isapproved = 1 ) 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

游魂 2024-10-01 08:17:16

我记得在某处看到的一种方法是,评论没有使用 Comment ID 和 Parent ID ,而是具有 Comment ID 和“排序键”,“排序键”是其祖先的所有 Comment ID 的串联。

例如,如果评论 1 有两个回复,评论 2 和 3,则排序键将为:

1 : 0001
2 : 0001.0002
3 : 0001.0003

那么如果有人回复评论 2,则会是..

4 : 0001.0002.0004

因此,如果您选择所有评论并按此排序键排序,它们就会掉出来以正确的顺序。

然后,要进行缩进,您只需查看排序键的长度即可了解注释的深度,并缩进适当的量。

添加评论很简单:新评论的排序键只是其父级的排序键,并在末尾添加了自己的 ID。

One approach I remember seeing somewhere was rather than using a Comment ID and a Parent ID , comments had a Comment ID and a "sort key" which was a concatenation of all the Comment IDs of their ancestors.

E.g. If comment 1 had two replies, comments 2 and 3, the sort keys would be:

1 : 0001
2 : 0001.0002
3 : 0001.0003

Then if someone replied to comment 2, it would be..

4 : 0001.0002.0004

So if you select all comments and sort by this sort key, they'll fall out in the right order.

Then, to do the indenting, you simply look at the length of the sort key to see how many levels deep the comment is, and indent an appropriate amount.

Adding comments is easy: the sort key of the new comment is simply it's parent's sort key, with its own ID added on to the end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文