网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Net;
using Dpz.Core.EnumLibrary;
using Dpz.Core.Hangfire;
using Dpz.Core.Web.Models;
using Hangfire;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace Dpz.Core.Web.Controllers;

public class CommentController(ICommentService commentService) : Controller
{
    [HttpGet("Comment/{node}/{relation}")]
    public async Task<IActionResult> Index(CommentNode node, string relation, int pageIndex = 1, int pageSize = 5)
    {
        relation = WebUtility.UrlDecode(relation);
        ViewData["node"] = node;
        ViewData["relation"] = relation;
        var list = await commentService.GetCommentsAsync(node, relation, pageIndex, pageSize);
        var count = await commentService.GetCommentCountAsync(node, relation);
        var model = new CommentPage { Page = list, Count = count };
        Response.Headers.Append("CommentCount", count.ToString());
        return PartialView(model);
    }

    [HttpGet("Comment/Page/{node}/{relation}")]
    public async Task<IActionResult> Page(CommentNode node, string relation, int pageIndex = 1, int pageSize = 5)
    {
        relation = WebUtility.UrlDecode(relation);
        ViewData["node"] = node;
        ViewData["relation"] = relation;
        var list = await commentService.GetCommentsAsync(node, relation, pageIndex, pageSize);
        var count = await commentService.GetCommentCountAsync(node, relation);
        var model = new CommentPage { Page = list, Count = count };
        Response.Headers.Append("CommentCount", count.ToString());
        return PartialView("_CommentListPartial", model);
    }

    [HttpPost, ValidateAntiForgeryToken]
    public async Task<IActionResult> Publish(VmPublishComment comment)
    {
        if (!ModelState.IsValid)
        {
            var errors = ModelState
                .SelectMany(x => x.Value?.Errors ?? new ModelErrorCollection())
                .Select(x => x.ErrorMessage)
                .Where(x => !string.IsNullOrEmpty(x))
                .ToArray();
            return Json(new ResultInfo(string.Join("\n", errors)));
        }

        await commentService.PublishCommentAsync(comment);
        var list = await commentService.GetCommentsAsync(comment.Node, comment.Relation, 1, 5);
        var count = await commentService.GetCommentCountAsync(comment.Node, comment.Relation);
        var model = new CommentPage { Page = list, Count = count };
        ViewData["node"] = comment.Node;
        ViewData["relation"] = comment.Relation;
        SetCookie(comment.NickName, comment.Email, comment.Site);
        BackgroundJob.Enqueue<EmailSenderActivator>(x => x.SendMasterAsync(comment));
        if (!string.IsNullOrEmpty(comment.ReplyId))
        {
            BackgroundJob.Enqueue<EmailSenderActivator>(x => x.SendCommenterAsync(comment));
        }

        ViewData["node"] = comment.Node;
        ViewData["relation"] = comment.Relation;
        Response.Headers.Append("CommentCount", count.ToString());
        return PartialView("_CommentListPartial", model);
    }

    [NonAction]
    private void SetCookie(string nickname, string email, string? site)
    {
        var cookieNickname = Request.Cookies[nameof(nickname)];
        if (string.IsNullOrEmpty(cookieNickname) || WebUtility.UrlDecode(cookieNickname) != nickname)
        {
            Response.Cookies.Append(nameof(nickname), WebUtility.UrlEncode(nickname),
                new CookieOptions
                    { HttpOnly = true, Secure = true, IsEssential = true, Expires = DateTimeOffset.Now.AddYears(1) });
        }

        var cookieEmail = Request.Cookies[nameof(email)];
        if (string.IsNullOrEmpty(cookieEmail) || WebUtility.UrlDecode(cookieEmail) != email)
        {
            Response.Cookies.Append(nameof(email), WebUtility.UrlEncode(email),
                new CookieOptions
                    { HttpOnly = true, Secure = true, IsEssential = true, Expires = DateTimeOffset.Now.AddYears(1) });
        }

        var cookieSite = Request.Cookies[nameof(site)];
        if (!string.IsNullOrEmpty(site) &&
            (string.IsNullOrEmpty(cookieSite) || WebUtility.UrlDecode(cookieSite) != site))
        {
            Response.Cookies.Append(nameof(site), WebUtility.UrlEncode(site),
                new CookieOptions
                    { HttpOnly = true, Secure = true, IsEssential = true, Expires = DateTimeOffset.Now.AddYears(1) });
        }
    }


    [HttpPost, ValidateAntiForgeryToken, CheckAuthorize]
    public async Task<IActionResult> Send(MembleComment comment)
    {
        if (!ModelState.IsValid)
        {
            var errors = ModelState
                .SelectMany(x => x.Value?.Errors ?? new ModelErrorCollection())
                .Select(x => x.ErrorMessage)
                .Where(x => !string.IsNullOrEmpty(x))
                .ToArray();
            return Json(new ResultInfo(string.Join("\n", errors)));
        }

        var user = User.GetIdentity();
        comment.User = user;
        await commentService.PublishCommentAsync(comment);
        var list = await commentService.GetCommentsAsync(comment.Node, comment.Relation, 1, 5);
        var count = await commentService.GetCommentCountAsync(comment.Node, comment.Relation);
        var model = new CommentPage { Page = list, Count = count };
        Response.Headers.Append("CommentCount", count.ToString());
        if (!string.IsNullOrEmpty(comment.ReplyId))
        {
            BackgroundJob.Enqueue<EmailSenderActivator>(x => x.SendCommenterAsync(comment));
        }

        ViewData["node"] = comment.Node;
        ViewData["relation"] = comment.Relation;
        return PartialView("_CommentListPartial", model);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码是一个 ASP.NET Core MVC 控制器,名为 CommentController,用于处理与评论相关的操作。以下是代码的主要功能和结构的详细解释:

1. 控制器概述

CommentController 依赖于一个 ICommentService 服务,该服务负责处理与评论相关的业务逻辑。控制器提供了多个操作(Action),用于获取评论、发布评论和处理用户的评论请求。

2. 方法详解

2.1 Index 方法

  • HTTP 方法: GET
  • 路由: Comment/{node}/{relation}
  • 功能:
    • 获取指定节点和关系的评论列表。
    • 解码 URL 中的 relation 参数。
    • 调用 commentService 获取评论列表和评论总数。
    • 将评论数据封装到 CommentPage 模型中,并返回一个部分视图(Partial View)。

2.2 Page 方法

  • HTTP 方法: GET
  • 路由: Comment/Page/{node}/{relation}
  • 功能:
    • 类似于 Index 方法,但返回的部分视图是 _CommentListPartial
    • 主要用于分页加载评论。

2.3 Publish 方法

  • HTTP 方法: POST
  • 功能:
    • 处理用户发布评论的请求。
    • 验证模型状态,如果无效,返回错误信息。
    • 调用 commentService 发布评论。
    • 获取最新的评论列表和总数,并更新视图数据。
    • 设置用户的 Cookie(昵称、邮箱、网站)。
    • 使用 Hangfire 发送电子邮件通知(如发送给管理员和评论者)。
    • 返回更新后的评论列表部分视图。

2.4 SetCookie 方法

  • 功能:
    • 设置用户的 Cookie,包括昵称、邮箱和网站。
    • 确保 Cookie 的安全性(HttpOnly 和 Secure),并设置过期时间为一年。

2.5 Send 方法

  • HTTP 方法: POST
  • 功能:
    • 处理用户发送评论的请求,类似于 Publish 方法。
    • 验证模型状态,发布评论,并返回更新后的评论列表部分视图。
    • 如果评论是回复,使用 Hangfire 发送通知给评论者。

3. 其他细节

  • 模型: CommentPage 用于封装评论列表和总数。
  • 错误处理: 在每个 POST 方法中,使用 ModelState 验证输入,并返回错误信息。
  • 安全性: 使用 ValidateAntiForgeryToken 特性来防止跨站请求伪造(CSRF)攻击。
  • Hangfire: 用于后台任务处理,例如发送电子邮件通知。

总结

CommentController 提供了一个完整的评论管理功能,包括获取评论、发布评论、处理用户输入和发送通知。它通过依赖注入的方式使用 ICommentService 来处理业务逻辑,并通过部分视图更新用户界面。

loading