《ASP.NET Web Forms 实现视频点赞功能的完整示例》

在现代Web开发中,实现一个动态的点赞功能是非常常见的需求。本文将详细介绍如何在ASP.NET Web Forms中实现一个视频点赞功能,包括前端页面的展示和后端的处理逻辑。我们将确保点赞数量能够实时更新,而无需刷新整个页面。

技术栈
项目结构
  • Play.aspx:前端页面
  • VideoLike.ashx:处理点赞和取消点赞的通用处理程序

详细功能介绍

前端页面 (Play.aspx)
  1. 页面布局

    • 使用 MasterPage 来组织页面结构,确保页面的一致性。
    • 使用 Repeater 控件来绑定视频信息,包括标题、位置、头像、昵称等。
  2. 视频播放器

    • 引入阿里云播放器的CSS和JS文件。
    • 创建一个新的 Aliplayer 实例,配置播放器的各项参数,如视频源、封面、自动播放等。
    • 监听截图事件,当用户点击截图按钮时,将截图保存为图片文件并下载。
  3. 点赞功能

    • 使用 like-icon 类来表示点赞图标,初始状态为白色(未点赞),点击后变为红色(已点赞)。
    • 使用 like-count 类来显示点赞数量,初始状态为0时显示"点赞"文本。
    • 当用户点击点赞图标时,通过AJAX请求调用后端处理程序 VideoLike.ashx,更新点赞状态和数量。
    • 成功处理后,更新前端显示的点赞数量和图标状态;失败处理时,恢复原状。
后端处理 (VideoLike.ashx)
  1. 处理请求

    • 设置响应内容类型为JSON。
    • 从请求参数中获取用户ID、视频ID和操作类型(点赞或取消点赞)。
  2. 业务逻辑

    • 使用 LikeMangerBLL 类来处理点赞和取消点赞的业务逻辑。
    • 根据操作类型调用相应的方法,更新点赞状态。
    • 返回成功或失败的响应结果。

前端页面 (Play.aspx)

aspx 复制代码
<%@ Page Title="" Language="C#" MasterPageFile="~/Main.Master" AutoEventWireup="true" CodeBehind="Play.aspx.cs" Inherits="HPITAixiu.Play" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <link rel="stylesheet" href="https://g.alicdn.com/apsara-media-box/imp-web-player/2.26.0/skins/default/aliplayer-min.css" />
    <style>
        .fab-title {
            width: 50%;
            left: calc(var(--f7-fab-margin) + var(--f7-safe-area-bottom));
            bottom: calc(var(--f7-fab-margin) + var(--f7-safe-area-bottom));
        }

        .title {
            width: 100%;
            margin-bottom: 10rem;
            background: rgba(0,0,0,0.4);
            padding: 0.2rem 0.8rem;
            border-radius: 0.3rem;
        }

        .avatar {
            width: 42px;
            height: 42px;
            border-radius: 42px;
        }

        .nickname {
            width: 4em;
            text-overflow: ellipsis;
        }
    </style>

</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <div class="pages">
        <div class="page" data-page="play">
            <div class="page-content">
                <div class="prism-player" id="player"></div>
            </div>
            <asp:Repeater ID="rptVideos" runat="server">
                <ItemTemplate>
                    <div class="fab fab-center-center fab-title" style="margin: 115px 0 80px 70px; width: 140px;">
                        <div class="title text-color-white">
                            <p><%#(Eval("Headline"))%></p>
                            <p style="font-size: 12px;"><i class="f7-icons size-14">placemark</i>[<%#(Eval("Location")??"未知")%>]</p>
                        </div>
                    </div>
                    <div class="fab fab-right-bottom" style="margin-bottom: 70px;">
                        <!-- 头像 -->
                        <a href="Videos.aspx?userId=<%#Eval("TBUsers.Id")%>" class="videos box-shadow-none bg-color-none external">
                            <img class="avatar" src="<%#(Eval("TBUsers.Avatar")??"/imgs/avatar.jpg")%>" />
                        </a>
                        <!-- 账号名 -->
                        <p class="nickname text-color-white text-align-center no-margin-top">
                            <%#(Eval("TBUsers.NickName"))%>
                        </p>
                        <!-- 点赞 -->
                        <a href="#" class="like box-shadow-none bg-color-none">
                            <i class="like-icon <%=IsLike?"text-color-pink":"text-color-white" %> icon f7-icons size-42">heart_fill</i>
                        </a>
                        <!-- 点赞数量 -->
                        <p class="like-count text-color-white text-align-center no-margin-top">
                            <%--<% if (LikeCount == 0){ %>点赞<% }else{%> <%} %>
                            <span class="dianzan"><% if (LikeCount == 0){ %>  <% }else{%><%=LikeCount %><%} %></span>--%>
                            
                            <%--<% if (LikeCount == 0) { %>
                                点赞
                            <% } else { %>
                                <span class="dianzan"><%= LikeCount %></span>
                            <% } %>--%>

                            <span class="like-text"><% if (LikeCount == 0) { %>点赞<% } %></span>
                            <span class="dianzan"><%= LikeCount > 0 ? LikeCount.ToString() : "" %></span>
                        </p>
                        <!-- 评论 -->
                        <a href="Discuss.aspx?videoId=<%#Eval("VideoId")%>" class="discuss box-shadow-none bg-color-none external">
                            <i class="discuss-icon icon f7-icons text-color-white size-42">chat_bubble_text</i>
                        </a>
                        <p class="discuss-count text-color-white text-align-center no-margin-top">
                        </p>
                    </div>
                </ItemTemplate>
            </asp:Repeater>
        </div>
    </div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ScripttPlaceHolder2" runat="server">
    <%--引入阿里云播放器的JavaScript库--%>
    <script src="https://g.alicdn.com/apsara-media-box/imp-web-player/2.26.0/aliplayer-min.js" type="text/javascript" charset="utf-8"></script>
    <script src="Scripts/jquery-3.7.0.min.js" type="text/javascript"></script>
    <script>
        // 创建一个新的Aliplayer实例
        var player = new Aliplayer({
            "id": "player",
            "source": "<%=PlayURL%>",
            "width": "100%",
            "height": "100%",
            "autoplay": false,  // 自动播放
            "isLive": false,
            "cover": "<%=CoverURL%>",
            "rePlay": true,
            "playsinline": true,
            "preload": true,
            "language": "zh-cn",
            "controlBarVisibility": "hover",
            // click点击显示时长
            //"showBarTime": 5000,
            "useH5Prism": true,
            "extraInfo": {
                "crossOrigin": "anonymous"
            },
            "skinLayout": [
                {
                    "name": "bigPlayButton",
                    "align": "blabs",
                    "x": 30,
                    "y": 80
                },
                {
                    "name": "H5Loading",
                    "align": "cc"
                },
                {
                    "name": "errorDisplay",
                    "align": "tlabs",
                    "x": 0,
                    "y": 0
                },
                {
                    "name": "infoDisplay"
                },
                {
                    "name": "tooltip",
                    "align": "blabs",
                    "x": 0,
                    "y": 56
                },
                {
                    "name": "thumbnail"
                },
                {
                    "name": "controlBar",
                    "align": "blabs",
                    "x": 0,
                    "y": 0,
                    "children": [
                        {
                            "name": "progress",
                            "align": "blabs",
                            "x": 0,
                            "y": 44
                        },
                        {
                            "name": "playButton",
                            "align": "tl",
                            "x": 15,
                            "y": 12
                        },
                        {
                            "name": "timeDisplay",
                            "align": "tl",
                            "x": 10,
                            "y": 7
                        },
                        {
                            "name": "fullScreenButton",
                            "align": "tr",
                            "x": 10,
                            "y": 12
                        },
                        {
                            "name": "subtitle",
                            "align": "tr",
                            "x": 15,
                            "y": 12
                        },
                        {
                            "name": "setting",
                            "align": "tr",
                            "x": 15,
                            "y": 12
                        },
                        {
                            "name": "volume",
                            "align": "tr",
                            "x": 5,
                            "y": 10
                        },
                        {
                            "name": "snapshot",
                            "align": "tr",
                            "x": 10,
                            "y": 12
                        }
                    ]
                }
            ]
        }, function (player) {  // 播放器创建成功的回调函数
            console.log("The player is created");   // 打印消息到控制台
        }
        );
        /* h5截图按钮, 截图成功回调 */
        //监听截图事件,当用户点击截图按钮时触发
        player.on('snapshoted', function (data) {
            var pictureData = data.paramData.base64
            var downloadElement = document.createElement('a')
            downloadElement.setAttribute('href', pictureData)
            var fileName = 'Aliplayer' + Date.now() + '.png'
            downloadElement.setAttribute('download', fileName)
            downloadElement.click()
            pictureData = null
        })


        var videoId = "<%=videoId%>";
        var userId = "<%=userId%>";
        // 点赞方法
        $$(".like-icon").on("click", function () {
            var likeText = $$(".like-text"); // 获取点赞文本元素
            var dianzan = $$(".dianzan"); // 获取点赞数量元素

            // 没有点赞
            if ($$(".like-icon").hasClass("text-color-white")) {
                // 将图标变成红色
                $$(".like-icon").addClass("text-color-pink").removeClass("text-color-white");

                // 更新点赞数量
                var currentCount = dianzan.html() === "" ? 0 : parseInt(dianzan.html(), 10);// 获取当前点赞数量,如果为空则初始化为0
                dianzan.html(currentCount + 1);// 增加点赞数量
                likeText.hide(); // 隐藏"点赞"文本

                // 调用BLL中的添加点赞方法,使用ajax连接一般处理程序
                $.post("ashx/VideoLike.ashx", { userId: userId, videoId: videoId, action: "addLike" }, function (response) {
                    if (response.success) {
                        // 成功处理
                    } else {
                        // 失败处理,例如恢复原状
                        dianzan.html(currentCount);
                        $$(".like-icon").addClass("text-color-white").removeClass("text-color-pink");// 恢复图标颜色
                        if (currentCount === 0) {
                            likeText.show();// 如果原来的点赞数量为0,显示"点赞"文本
                        }
                    }
                }, "json");
            } else {
                // 将图标变回白色
                $$(".like-icon").removeClass("text-color-pink").addClass("text-color-white");

                // 更新点赞数量
                var currentCount = parseInt(dianzan.html(), 10);// 获取当前点赞数量
                if (currentCount > 0) {
                    dianzan.html(currentCount - 1);// 减少点赞数量
                    if (currentCount - 1 === 0) {
                        dianzan.html("");// 如果减少后的点赞数量为0,清空点赞数量
                        likeText.show();// 显示"点赞"文本
                    }
                }

                // 调用BLL中的取消点赞方法,使用ajax连接一般处理程序
                $.post("ashx/VideoLike.ashx", { userId: userId, videoId: videoId, action: "removeLike" }, function (response) {
                    if (response.success) {
                        // 成功处理
                    } else {
                        // 失败处理,例如恢复原状
                        dianzan.html(currentCount); // 恢复原来的点赞数量
                        $$(".like-icon").addClass("text-color-pink").removeClass("text-color-white");// 恢复图标颜色
                        if (currentCount === 1) {
                            dianzan.html("");// 如果原来的点赞数量为1,清空点赞数量
                            likeText.show();// 显示"点赞"文本
                        }
                    }
                }, "json");
            }
        });
    </script>
</asp: Content>

后端处理 (VideoLike.ashx)

csharp 复制代码
using HPIT.BLL;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace HPITAixiu.ashx
{
    /// <summary>
    /// VideoLike 的摘要说明
    /// </summary>
    public class VideoLike : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";

            string videoId = context.Request.Form["videoId"];// 获取请求中的视频ID
            string userId = context.Request.Form["userId"];// 获取请求中的用户ID
            string action = context.Request.Form["action"];// 获取请求中的操作类型(addLike或removeLike)
            // 创建点赞管理业务逻辑层对象
            LikeMangerBLL likeMangerBLL = new LikeMangerBLL();
            bool success = false;
            // 如果获取action是addLike就调用BLL中的添加点赞方法
            if (action == "addLike")
            {
                // 调用BLL中的添加点赞方法
                success = likeMangerBLL.AddLike(videoId, int.Parse(userId));
            }
            // 否则调用移除方法
            else if (action == "removeLike")
            {
                // 调用BLL中的取消点赞方法
                success = likeMangerBLL.removeLike(videoId, int.Parse(userId));
            }
            // 创建响应对象
            var response = new { success = success };
            // 将响应对象序列化为JSON并写入响应
            context.Response.Write(JsonConvert.SerializeObject(response));
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

总结

通过上述代码,我们实现了一个完整的视频点赞功能。前端页面使用ASP.NET Web Forms和jQuery,后端使用C#和AJAX进行数据交互。点赞数量能够实时更新,用户体验良好。希望本文对你有所帮助,如果有任何问题或建议,欢迎留言交流!

参考资料

希望这篇博文对你有帮助!如果有任何问题或需要进一步优化,请随时告诉我。

相关推荐
web147862107236 分钟前
C# .Net Web 路由相关配置
前端·c#·.net
m0_748247806 分钟前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖10 分钟前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案117 分钟前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_7482548822 分钟前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.34 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营38 分钟前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
学代码的小前端1 小时前
0基础学前端-----CSS DAY9
前端·css
joan_851 小时前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui