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

news2024/11/30 5:45:09

在这里插入图片描述

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

技术栈
  • ASP.NET Web Forms
  • C#
  • jQuery
  • AJAX
项目结构
  • 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)

<%@ 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)

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进行数据交互。点赞数量能够实时更新,用户体验良好。希望本文对你有所帮助,如果有任何问题或建议,欢迎留言交流!

参考资料

  • ASP.NET Web Forms 官方文档
  • jQuery 官方文档
  • AJAX 官方文档

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2191724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大厂出来的人为什么不比你高效?

在最近参加的一个线下聚会上&#xff0c;有人问我&#xff1a;“我们单位有来自阿里、腾讯、华为这些大厂的人&#xff0c;为什么我没觉得他们做事比我们这些没大厂经历的人更有章法和效率&#xff1f;”你别说&#xff0c;这一问所反映的现象&#xff0c;与我在阿里巴巴工作时…

10月6日星期日今日早报简报微语报早读

10月6日星期日&#xff0c;农历九月初四&#xff0c;早报#微语早读。 1、国家体育总局&#xff1a;体育不允许成为畸形饭圈文化继续滋生的“温床”&#xff1b; 2、10月起上海适老化改造最高可享补贴三千元&#xff0c;补贴范围扩大&#xff1b; 3、国内航线燃油附加费10月5…

Java版本的SSE服务端实现样例

简单记录一下使用netty方式实现SSE的服务端功能 目录 简要说明基于Netty功能需求后端代码1. 创建一个SpringBoot 应用2. 创建服务端功能3. 创建前端功能4. 测试SSE 总 结 简要说明 Server-Sent Events (SSE) 是一种用于在客户端和服务器之间建立单向通信的技术。 它允许服务器…

【复习】JS中的数据类型

文章目录 数据类型UndefinedNullBooleanNumberStringSymbolBigIntObjectArrayFunctionDateRegExp 数据类型 其实就两种&#xff0c;原始数据类型&#xff08;Primitive Types&#xff09;和引用数据类型&#xff08;Reference Types&#xff09; JS将数据分为七种数据类型&…

降压芯片TPS54821

降压芯片TPS54821 介绍 价格低廉&#xff0c;只需1.5元。是一个同步整流降压BUCK电路。MOS管内置。输入电压为4.5V至17V&#xff0c;输出电压为0.6V到15V&#xff0c;输出电流最大到8A。是QFN封装&#xff0c;焊接时有些许困难。得益于QFN封装&#xff0c;其引线电感非常的小…

振动分析-30-振动信号的幅值概率密度函数CWRU西楚大学轴承数据(实战)

文章目录 1 背景2 幅值概率密度函数3 实现流程3.1 自定义函数3.2 模拟正弦信号4 CWRU轴承数据4.1 加载数据4.2 相同工况不同故障4.3 相同数据不同份数5 参考附录1 背景 很多初学者刚接触故障诊断可能觉得很简单,套用深度学习模型进行训练,分类准确率达到99%即可。 在写论文时…

LabVIEW提高开发效率技巧----严格类型化定义

在LabVIEW开发过程中&#xff0c;严格类型化定义&#xff08;Strict Typedefs&#xff09; 是一种工具&#xff0c;用于保证程序中控件和常量的一致性&#xff0c;减少错误&#xff0c;提高维护效率。通过使用严格类型化定义&#xff0c;开发者可以确保在程序的多个地方引用相同…

Day02-MySQL数据库服务体系结构

Day02-MySQL数据库服务体系结构 1、数据库服务连接管理2、数据库服务应用配置2.1 服务进行配置有什么作用&#xff1f;2.2 应用配置有三种方式&#xff1a; 3、数据库服务多实例构建4、数据库服务版本升级4.1 实现升级的方法&#xff1a;4.2 常见的数据库服务程序升级方式&…

【深入理解SpringCloud微服务】手写实现断路器算法

【深入理解SpringCloud微服务】手写实现断路器算法 断路器状态切换断路器接口断路器算法实现相关属性failed()success()canPass() 断路器状态切换 在分析断路器算法前&#xff0c;我们先复习一下断路器的状态转换。 断路器一般有三个状态&#xff1a;关闭、打开、半开。 断路…

【瑞昱RTL8763E】歌曲传输

1 概要 Watch 端 SD 卡中的歌曲除了可以通过 USB 传输&#xff0c;还可以通过 SPP/BLE 传输来完成歌曲的添加与删 除操作。其中&#xff0c;Android 手机可以安装 LocalPlayback.apk 使用 SPP 协议与 watch 交互&#xff1b;iOS 手机可以安装 LocalPlayback.ipa 通过 BLE 与 wa…

Python 工具库每日推荐 【Matplotlib】

文章目录 引言Python数据可视化库的重要性今日推荐:Matplotlib工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例:数据分析可视化案例分析高级特性自定义样式动画效果3D绘图性能优化技巧扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 T…

【可答疑】基于51单片机的无线病床呼叫系统(含仿真、代码、报告、演示视频等)

✨哈喽大家好&#xff0c;这里是每天一杯冰美式oh&#xff0c;985电子本硕&#xff0c;大厂嵌入式在职0.3年&#xff0c;业余时间做做单片机小项目&#xff0c;有需要也可以提供就业指导&#xff08;免费&#xff09;~ &#x1f431;‍&#x1f409;这是51单片机毕业设计100篇…

什么是虚拟化?| 裸机 vs 虚拟机 vs 容器

“云计算&#xff01;DevOps&#xff01;Docker&#xff01;Kubernetes&#xff01;……” 如果您是一名软件工程师&#xff0c;还没有遇到过以上这些流行词&#xff0c;那么您可能一直生活在与世隔绝的地方。 所有这些技术都与同一样东西有关&#xff0c;对&#xff0c;就是…

openEuler 24.03 (LTS) 部署 K8s(v1.31.1) 高可用集群(Kubespray Ansible 方式)

写在前面 实验需要一个 CNI 为 flannel 的 K8s 集群之前有一个 calico 的版本有些旧了,所以国庆部署了一个v1.31.1 版本 3 * master 5 * work时间关系直接用的工具 kubespray博文内容为部署过程以及一些躺坑分享需要科学上网理解不足小伙伴帮忙指正 &#x1f603;,生活加油 99…

IEC104规约的秘密之七----配置参数t1,t2,t3

104通讯前需要配置通讯参数&#xff0c;一般有如下参数&#xff1a; IP地址&#xff0c;端口号&#xff0c;k&#xff0c;w&#xff0c;t1&#xff0c;t2&#xff0c;t3&#xff0c;公共地址&#xff0c;遥控超时参数&#xff0c;104主规约还有一个t0参数。 本次只讲解t1&#…

2-113 基于matlab的图像的配准融合

基于matlab的图像的配准融合&#xff0c;采用互信息配准&#xff0c;PV差值&#xff0c;powell算法&#xff0c;小波变换的图像融合算法。在GUI界面输入两幅图像&#xff0c;完成图像的配准融合。融合图像要求像素 一样。程序代码已经有详细的注释。程序已调通&#xff0c;可直…

对操作系统中的用户态和内核态的理解

目录 引言 为什么要有用户态和内核态&#xff1f;只有一个内核态不行么&#xff1f; 一、用户态&#xff08;User Mode&#xff09; 定义 特点 应用 二、内核态&#xff08;Kernel Mode&#xff09; 定义 特点 应用 三、用户态与内核态的联系和区别 四、用户态和内…

通过dem2terrain生成MapboxGL地形服务

概述 MapboxGL在2的版本之后通过地形服务开始支持三维的展示了&#xff0c;之前也有文章“mapboxGL2中Terrain的离线化应用”对该服务进行过说明与分析。前些天在翻公众号的时候翻到了dem2terrain可以生成地形服务&#xff0c;同时做了一些优化&#xff0c;今天就给大家分享一…

2024全面升级!从零开始的大模型开发学习路线图——精通之路

第一阶段&#xff1a;基础理论入门 目标&#xff1a;了解大模型的基本概念和背景。 内容&#xff1a; 人工智能演进与大模型兴起。 大模型定义及通用人工智能定义。 GPT模型的发展历程。 第二阶段&#xff1a;核心技术解析 目标&#xff1a;深入学习大模型的关键技术和工…

多文件并发多线程MD5工具(相对快速的MD5一批文件),适配自定义MD5 Hash I/O缓存。

自己写的多文件 MD5校验工具&#xff0c;一个文件开一个线程&#xff0c;有最大I/O 缓存设置&#xff0c;兼容读写MD5后缀文件。 共计91个文件&#xff0c;合计180G左右 12分钟左右&#xff0c;UI基本卡废&#xff0c;但程序没蹦&#xff0c;属于正常。 卡的原因是基本是用 I/O…