当前位置: 首页 > news >正文

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

在这里插入图片描述

在现代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.base64var 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);// 获取当前点赞数量,如果为空则初始化为0dianzan.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"];// 获取请求中的视频IDstring userId = context.Request.Form["userId"];// 获取请求中的用户IDstring 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 官方文档

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

相关文章:

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

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

Linux SSH服务

Linux SSH&#xff08;Secure Shell&#xff09;服务是一种安全的远程登录协议&#xff0c;用于在Linux操作系统上远程登录和执行命令。它提供了加密的通信通道&#xff0c;可以在不安全的网络环境中安全地进行远程访问。 SSH服务在Linux系统中通常使用OpenSSH软件包来实现。它…...

MySQL--视图(详解)

目录 一、前言二、视图2.1概念2.2语法2.3创建视图2.3.1目的 2.4查看视图2.5修改数据2.5.1通过真实表修改数据&#xff0c;会影响视图2.5.2通过修改视图&#xff0c;会影响基表 2.6注意2.7 删除视图2.8 视图的优点 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&…...

Javascript 普通非async函数调用async函数

假设我们有一个异步函数 async function asyncFunction() {console.log("开始执行异步函数");await new Promise(resolve > setTimeout(resolve, 1000)); // 模拟异步操作console.log("异步函数执行完毕"); } 我们在调用这个异步函数时&#xff0c;比…...

【LeetCode】修炼之路-0004-Median of Two Sorted Arrays【python】

题目 Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be O(log (mn)). Example 1: Input: nums1 [1,3], nums2 [2] Output: 2.00000 Explanation: merged…...

C++面试速通宝典——10

177. #include <filename> 和 #include "filname.h" 有什么区别&#xff1f; ‌‌‌‌  对于 #include <filename> &#xff0c; 编译器从标准库路径开始搜索 filename.h。 ‌‌‌‌  对于 #include "filename.h&#xff0c;编译器从用户的工作…...

肺腺癌预后新指标:全切片图像中三级淋巴结构密度的自动化量化|文献精析·24-10-09

小罗碎碎念 本期这篇文章&#xff0c;我去年分享过一次。当时发表在知乎上&#xff0c;没有标记参考文献&#xff0c;配图的清晰度也不够&#xff0c;并且分析的还不透彻&#xff0c;所以趁着国庆假期重新分析一下。 这篇文章的标题为《Computerized tertiary lymphoid structu…...

基于jmeter+perfmon的稳定性测试记录

1. 引子 最近承接了项目中一些性能测试的任务&#xff0c;因此决定记录一下&#xff0c;将测试的过程和一些心得收录下来。 说起来性能测试算是软件测试行业内&#xff0c;有些特殊的部分。这部分的测试活动&#xff0c;与传统的测试任务差别是比较大的&#xff0c;也比较依赖…...

前沿论文 M5Product 组会 PPT

对比学习&#xff08;Contrast learning&#xff09;&#xff1a;对比学习是一种自监督学习方法&#xff0c;用于在没有标签的情况下&#xff0c;通过让模型学习哪些数据点相似或不同来学习数据集的一般特征。假设一个试图理解世界的新生婴儿。在家里&#xff0c;假设有两只猫和…...

navicat~导出数据库密码

当我们mysql密码忘记了&#xff0c;而在navicat里有记录&#xff0c;我们应该如何导出这个密码呢&#xff1f; 第一步:文件菜单&#xff0c;导出链接&#xff0c;导出连接获取到 connections.ncx 文件 这里需要勾选 导出密码&#xff01;&#xff01;&#xff01; 不然导出的文…...

【Java】 —— 数据结构与集合源码:Vector、LinkedList在JDK8中的源码剖析

目录 7.2.4 Vector部分源码分析 7.3 链表LinkedList 7.3.1 链表与动态数组的区别 7.3.2 LinkedList源码分析 启示与开发建议 7.2.4 Vector部分源码分析 jdk1.8.0_271中&#xff1a; //属性 protected Object[] elementData; protected int elementCount;//构造器 public …...

YOLOv5改进——添加SimAM注意力机制

目录 一、SimAM注意力机制核心代码 二、修改common.py 三、修改yolo.py ​三、建立yaml文件 四、验证 一、SimAM注意力机制核心代码 在models文件夹下新建modules文件夹&#xff0c;在modules文件夹下新建一个py文件。这里为simam.py。复制以下代码到文件里面。 import…...

SQL 自学:表别名的运用与对被联结表使用聚集函数

一、表别名的概念与作用 &#xff08;一&#xff09;表别名的定义 表别名是为表指定的临时名称&#xff0c;在 SQL 查询中使用别名可以简化表名&#xff0c;提高代码的可读性和可维护性。当表名较长或在复杂的查询中多次引用表时&#xff0c;使用表别名可以避免重复输入冗长的…...

jmeter学习(2)变量

1&#xff09;用户定义的变量 路径&#xff1a;添加-》配置元件-》用户定义的变量 用户定义的变量是全局变量&#xff0c;可以跨线程组被调用&#xff0c;但在启动运行时获取一次值&#xff0c;在运行过程中不再动态获取值。 注意的是&#xff0c;如果在某个线程组定义了全…...

【C#生态园】C#文件压缩库全面比较:选择最适合你的库

从核心功能到API概览&#xff1a;深度解析六大C#文件压缩库 前言 在软件开发过程中&#xff0c;文件的压缩和解压缩是一个常见的需求。针对C#开发者而言&#xff0c;选择合适的文件压缩库可以极大地简化开发工作。本文将介绍几个常用的C#文件压缩库&#xff0c;包括其核心功能…...

【测试】接口测试与接口自动化

壹、接口测试基础 一、接口测试概念 I、基础概念 是测试系统组件间接口的一种测试。 主要用于检测外部系统与系统间、内部子系统间的交互点&#xff1b;测试重点检查数据的交换、传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系。 内部接口调用相当于函数调用&am…...

Android设置边框圆角

在Android开发中&#xff0c;圆角设计十分常见&#xff0c;那么实现边框圆角有几种形式呢&#xff1f; 文章目录 设置圆角边框样式使用ClipToOutline进行裁切最后 设置圆角边框样式 常见的方式是在drawable文件夹下设置一个xml文件的边框样式&#xff0c;比如 <shape andro…...

SpringBoot项目打成jar包,在其他项目中引用

1、首先新建一个SpringBoot工程 记得要将Gradle换成Maven 2、新建一个要引用的方法 3、打包的时候要注意&#xff1a; ① 不能使用springboot项目自带的打包插件进行打包&#xff0c;下面是自带的&#xff1a; ②要换成传统项目的maven打包&#xff0c;如下图&#xff1a; 依…...

【音频可视化】通过canvas绘制音频波形图

前言 这两天写项目刚好遇到Ai对话相关的需求&#xff0c;需要录音功能&#xff0c;绘制录制波形图&#xff0c;写了一个函数用canvas实现可视化&#xff0c;保留分享一下&#xff0c;有需要的直接粘贴即可&#xff0c;使用时传入一个1024长的&#xff0c;0-255大小的Uint8Arra…...

解决github每次pull push输入密码问题

# 解决git pull/push每次都需要输入密码问题 git bash进入你的项目目录&#xff0c;输入&#xff1a; git config --global credential.helper store然后你会在你本地生成一个文本&#xff0c;上边记录你的账号和密码。配置项写入到 "C:\Users\用户名\ .gitconfig" …...

Java重修笔记 第六十四天 坦克大战(十四)IO 流 - 标准输入输出流、InputStreamReader 和 OutputStreamWriter

标准输入输出流 1. System.in 标准输入流 本质上是一个InputString&#xff0c;对应键盘&#xff0c;表示从键盘输入。 定义&#xff1a;public final static InputStream in null; 所以 Scanner scanner new Scanner(System.in); 会从键盘中获取数据 2. System.out 标准输…...

prctl的函数和pthread_self函数

1.prctl的函数原型如下&#xff1a; #include<sys/prctl.h> ​prctl(PR_SET_NAME, “process_name”);第一个参数是操作类型&#xff0c;指定PR_SET_NAME&#xff08;对应数字15&#xff09;&#xff0c;即设置进程名&#xff1b; 第二个参数是进程名字符串&#xff0c;…...

Vim 命令行模式下的常用命令

Vim 命令行模式下的常用命令 文件操作&#xff1a; :w &#xff1a;保存当前文件。:w filename &#xff1a;将当前内容另存为指定的 filename 。:q &#xff1a;退出 Vim&#xff0c;如果文件有修改但未保存&#xff0c;会提示错误。:q! &#xff1a;强制退出 Vim&#xff0c…...

【动态规划-最长递增子序列(LIS)】力扣2826. 将三个组排序

给你一个整数数组 nums 。nums 的每个元素是 1&#xff0c;2 或 3。在每次操作中&#xff0c;你可以删除 nums 中的一个元素。返回使 nums 成为 非递减 顺序所需操作数的 最小值。 示例 1&#xff1a; 输入&#xff1a;nums [2,1,3,2,1] 输出&#xff1a;3 解释&#xff1a; …...

Elastic Stack--16--ES三种分页策略

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 方式一&#xff1a;from size实现原理使用方式优缺点 方式二&#xff1a;scroll实现原理使用方式优缺点 方式三&#xff1a;search_after实现原理使用方式优缺点 三…...

[LeetCode] 315. 计算右侧小于当前元素的个数

题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;按要求返回一个新数组 counts 。数组 counts 有该性质&#xff1a; counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。 题目链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 题目主要思路&a…...

【hot100-java】二叉树展开为链表

二叉树篇。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …...

如何在在 YOLOv3模型中添加Attention机制

在YOLOv3模型中添加Attention机制需要以下几个步骤&#xff1a; 1. 规定格式 当添加新的模块&#xff08;如Attention机制模块&#xff09;时&#xff0c;需要像定义[convolutional]、[maxpool]等层在cfg文件中的格式一样&#xff0c;对新模块进行格式规定。例如对于SE模块&a…...

单点登录Apereo CAS 7.1安装配置教程

笔者目前正在做一个单点登录的课题,历时较长总算摸到一些门路,其中的辛酸不易按下不表。截至本文发布,CAS的最新版本为7.1。由于涉及到课题内容,而且内容比较新,整理试验不容易,暂时只对VIP开放,后续课题完成后会完全开放,敬请谅解。 CAS项目区别 在CAS的项目选择上,…...

windows C++-移除界面工作线程(一)

本文档演示了如何使用并发运行时将 Microsoft 基础类 (MFC) 应用程序中由用户界面 (UI) 线程执行的工作移动到工作线程。 本文档还演示了如何提高冗长绘制操作的性能。 通过将阻塞性操作&#xff08;例如&#xff0c;绘制&#xff09;卸载到工作线程来从 UI 线程中移除工作&am…...