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

news2024/10/10 5:58: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/2201244.html

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

相关文章

Java进阶之路—单元测试Juint(完整详解Juint使用以及Juin注解,附有代码+案例)

文章目录 单元测试Juint35.1 概述35.2 用法手动导包正确的使用方式 35.3 Junit常用注解 单元测试Juint 35.1 概述 针对最小功能单元编写测试代码&#xff0c;Java中最小功能单元是方法&#xff0c;因此单元测试就是针对Java方法的测试。 对部分代码进行测试。 35.2 用法 &…

【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的新能源停车场管理系统

开题报告 随着新能源汽车的快速普及和普及&#xff0c;新能源车辆的停车和充电需求也越来越大。传统的停车场管理系统无法满足这些新能源车辆的特殊需求&#xff0c;如充电桩分配、充电桩使用情况的实时监测等。因此&#xff0c;开发一种基于 Java 的新能源停车场管理系统成为…

计算机视觉之YOLO算法基本原理和应用场景

YOLO算法基本原理 整体流程 YOLO 将目标检测问题转化为一个回归问题。它将输入图像划分成多个网格单元&#xff0c;每个网格单元负责预测中心点落在该网格内的目标。对于每个网格单元&#xff0c;YOLO 预测多个边界框以及这些边界框中包含目标的类别概率。边界框通常由中心点坐…

Spring Cloud Stream 3.x+kafka 3.8整合

Spring Cloud Stream 3.xkafka 3.8整合&#xff0c;文末有完整项目链接 前言一、如何看官方文档(有深入了解需求的人)二、kafka的安装tar包安装docker安装 三、代码中集成创建一个测试topic&#xff1a;testproducer代码producer配置&#xff08;配置的格式&#xff0c;上篇文章…

PHP中的HTTP请求:简化你的网络通信

在当今的网络应用开发中&#xff0c;PHP作为一种流行的服务器端脚本语言&#xff0c;经常需要与外部服务进行通信。这通常涉及到发送HTTP请求来获取或提交数据。幸运的是&#xff0c;PHP提供了多种方式来简化HTTP请求的过程&#xff0c;使得网络通信变得轻而易举。 PHP中的HTTP…

stm32h743 threadx + filex(SD卡读写) + CubeMX + CubeIDE

今天整了一下正点原子阿波罗h743的filex,按部就班的使用CubeMX去搭建环境,再用CubeIDE去编写程序,里面也有几个小坑,问题不大。 Step1. 创建CubeMX 首先设置RCC晶振,SYS为tim6 然后勾选sdmmc1 选择4bits,分频系数为4。这个分频系数选4对应一般的sd卡都可以用了,如果好…

单片机死机后在不破坏现场的情况下连接调试器进入调试模式

经常遇到程序在现场卡死了&#xff0c;但是这个时候没有连接调试器&#xff0c;不好找死机原因。 下面说下在程序卡死的时候&#xff0c;在不破坏死机现场的情况下&#xff0c;连接上调试器进行程序调试的方法。 把调试器连接电脑&#xff0c;打开keil做下面的配置&#xff0c…

Llama系列上新多模态!3.2版本开源超闭源,还和Arm联手搞了手机优化版,Meta首款多模态Llama 3.2开源!1B羊驼宝宝,跑在手机上了

Llama系列上新多模态&#xff01;3.2版本开源超闭源&#xff0c;还和Arm联手搞了手机优化版&#xff0c;Meta首款多模态Llama 3.2开源&#xff01;1B羊驼宝宝&#xff0c;跑在手机上了&#xff01; 在多模态领域&#xff0c;开源模型也超闭源了&#xff01; 就在刚刚结束的Met…

Web自动化Demo-PHP+Selenium

1.新建工程 打开PhpStorm新建工程如下&#xff1a; 打开终端输入如下命令安装selenium&#xff1a; composer require php-webdriver/webdriver 2.编写代码 <?php require vendor/autoload.php;use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver…

分治算法(8)_归并排序_翻转对

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 分治算法(8)_归并排序_翻转对 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 温…

云原生日志ELK( logstash安装部署)

logstash 介绍 LogStash由JRuby语言编写&#xff0c;基于消息&#xff08;message-based&#xff09;的简单架构&#xff0c;并运行在Java虚拟机 &#xff08;JVM&#xff09;上。不同于分离的代理端&#xff08;agent&#xff09;或主机端&#xff08;server&#xff09;&…

【python】:pycharm2024.2.2使用

参考链接&#xff1a; 文件连接&#xff1a; 方法1&#xff1a;临时有效&#xff0c;后期官方更新提示激活无效 输入激活码&#xff1a; X9MQ8M5LBM-eyJsaWNlbnNlSWQiOiJYOU1ROE01TEJNIiwibGljZW5zZWVOYW1lIjoiZ3VyZ2xlcyB0dW1ibGVzIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVF…

Chainlit集成Dashscope实现语音交互网页对话AI应用

前言 本篇文章讲解和实战&#xff0c;如何使用Chainlit集成Dashscope实现语音交互网页对话AI应用。实现方案是对接阿里云提供的语音识别SenseVoice大模型接口和语音合成CosyVoice大模型接口使用。针对SenseVoice大模型和CosyVoice大模型&#xff0c;阿里巴巴在github提供的有开…

视频流媒体融合与视频监控汇聚管理系统集成方案

流媒体视频融合与汇聚管理系统可以实现对各类模块化服务进行统一管理和配置等操作&#xff0c;可实现对应用服务的整合、管理及共享&#xff0c;以标准接口的方式&#xff0c;业务平台及其他第三方业务平台可以方便地调用各类数据&#xff0c;具有开放性和可扩展性。在流媒体视…

opencascade鼠标拖拽框选功能

1.首先在OccView中添加用于显示矩形框的类 //! rubber rectangle for the mouse selection.Handle(AIS_RubberBand) mRectBand; 2.设置框选的属性 mRectBand new AIS_RubberBand(); //设置属性 mRectBand->SetLineType(Aspect_TOL_SOLID); //设置变宽线型为实线 mRe…

scanMiR:使用R语言预测 miRNA 结合位点

生信碱移 scanMiR 结合预测 scanMiR&#xff0c;一款R语言工具包&#xff0c;能够高效地扫描任何自定义序列上的典型和非典型miRNA结合位点&#xff0c;估计解离常数并预测聚合的转录物抑制。 最近&#xff0c;几项高通量研究试图阐明miRNA–mRNA靶向的生化决定因素。在一项发…

Unity 克隆Timeline并保留引用

Timeline的资源是.playable文件&#xff0c;简单的复制不会保留引用关系。 下面的脚本可以复制引用关系。 using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; using UnityEngine.Playables; using UnityEngine.Timeline; u…

Node.js入门——fs、path模块、URL端口号、模块化导入导出、包、npm软件包管理器

Node.js入门 1.介绍 定义&#xff1a;跨平台的JS运行环境&#xff0c;使开发者可以搭建服务器端的JS应用程序作用&#xff1a;使用Node.Js编写服务器端代码Node.js是基于Chrome V8引擎进行封装&#xff0c;Node中没有BOM和DOM 2.fs模块-读写文件 定义&#xff1a;封装了与…

(03)python-opencv图像处理——图像的几何变换

前言 1、变换 2、缩放 3、平移变换 4、旋转 5、仿射变换 6、翻转 参考文献 前言 在本教程中&#xff1a; 你将会学到将不同的几何变换应用于图像&#xff0c;如平移、旋转、仿射变换等。你会学到如下函数&#xff1a;cv.getPerspectiveTransform 图像的几何变换是图像…

Ping32引领数据防泄漏新潮流:智能、高效、安全

在当今数字化迅猛发展的时代&#xff0c;企业面临着日益严峻的数据安全挑战。数据泄漏事件频发&#xff0c;不仅损害企业声誉&#xff0c;还可能导致巨额的经济损失。为此&#xff0c;Ping32以其创新的数据防泄漏解决方案&#xff0c;正在引领行业新潮流。其技术特点可概括为“…