Logo

.Net6简单使用WebSocket

photo

2024年06月17日

1:WebSocket简介

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

大家可以查看菜鸟中的说明 https://www.runoob.com/html/html5-websocket.html

  WebSocket可以通过JS与服务器端建立实时的双向通信,它主要包括:2个核心方法、4个监听函数、1个核心属性。

2个核心方法:

  ① send() 向远程服务器发送信息

  ② close() 关闭与远程服务器的连接

4个监听函数:

  ① onopen 当网络连接建立成功时触发该事件
  ② onerror 当网络发生错误时触发该事件
  ③ onclose 当网络连接被关闭时触发该事件
  ④ onmessage 当websocket接收到服务器发来的消息的时触发该事件

1个核心属性:readyState,它有四种状态

  ① WebSocket.OPEN:表示与服务器已经建立好连接

  ② WebSocket.CLOSED:表示与服务器连接已经断开

  ③ WebSocket.CONNECTING:表示正在尝试与服务建立连接

  ④ WebSocket.CLOSING:表示正在关闭与服务器连接

服务器端主要用到两个方法:

  ① SendAsync() 发送信息给客户端

  ② CloseAsync() 关闭该Socket连接:

2:主要code

js部分

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<div class="container">
    <div>
        <table>
            <tr><td>ID:</td><td><input id="useid" type="text" placeholder="请输入人员ID" /></td></tr>
            <tr><td>昵称:</td><td><input id="usenike" type="text" placeholder="请输入人员昵称" /></td></tr>
            <tr><td><button id="btnJoin">join room</button> </td><td><button id="btnLeave">leave room</button></td></tr>
            <tr>
                <td>
                    <input id="touid" type="text" placeholder="请输入接收人员ID" /> 消息:<input type="text" id="txtMsg" value="" />
                </td>
                <td>
                    <button id="btnSend">单聊</button>
                </td>
            </tr>
            <tr><td><button id="btnAllsend">群聊</button></td></tr>
        </table>
        <div>
            <textarea style="height:300px;width:400px" id="msgList"></textarea>
        </div>
    </div>
</div>
@section Scripts{
    <script type="text/javascript">
        $(function () {
            var server = 'ws://localhost:5000'; //如果开启了https则这里是wss
            var WEB_SOCKET = new WebSocket(server + '/ws');
            WEB_SOCKET.onopen = function (evt) {
                console.log('Connection open ...');
                $('#msgList').val('websocket connection opened .');
            };

            WEB_SOCKET.onmessage = function (evt) {
                console.log('Received Message: ' + evt.data);
                if (evt.data) {
                    var content = $('#msgList').val();
                    content = content + '\r\n' + evt.data;

                    $('#msgList').val(content);
                }
            };

            WEB_SOCKET.onerror = function (evt) {
                if (evt) {
                    console.log(evt.data);
                }
            };

            WEB_SOCKET.onclose = function (evt) {
                console.log('Connection closed.');
                console.log("=======" + evt);
                var content = $('#msgList').val();
                content = content + '\r\n' + evt;
                $('#msgList').val(content);
                WEB_SOCKET.readyState = closed;
            };
            //加入聊天室
            $('#btnJoin').on('click', function () {
                var useid = $('#useid').val();
                var nick = $('#usenike').val();
                if (useid) {
                    var msg = {
                        Action: 7,
                        RoomId: 0,
                        Uid: useid,
                        MsgInfo: nick + "加入到群聊"
                    };
                    if (WEB_SOCKET == null || !WEB_SOCKET) {
                        WEB_SOCKET.readyState = open();
                        //WEB_SOCKET = new WebSocket(server + '/ws');
                    }
                    WEB_SOCKET.send(JSON.stringify(msg));
                }
            });
            //发送消息
            $('#btnSend').on('click', function () {
                var useid = $('#useid').val();
                var touid = $("#touid").val();
                var usenike = $('#usenike').val();
                var message = $('#txtMsg').val();
                if (message) {
                    WEB_SOCKET.send(JSON.stringify({
                        Action: 8,//8:单聊
                        MsgInfo: message,
                        nick: usenike,
                        ToUid: touid,
                        Uid: useid
                    }));
                }
            });
            //群聊
            $('#btnAllsend').on("click", function () {
                var useid = $('#useid').val();
                var touid = $("#touid").val();
                var usenike = $('#usenike').val();
                var message = $('#txtMsg').val();
                if (message) {
                    WEB_SOCKET.send(JSON.stringify({
                        Action: 9,//9:群聊
                        MsgInfo: message,
                        nick: usenike,
                        //ToUid: touid,
                        Uid: useid,
                        RoomId: 0//群ID
                    }));
                }
            });

            $('#btnLeave').on('click', function () {
                var nick = $('#usenike').val();
                var useid = $('#useid').val();
                var msg = {
                    Action: 10,//10:退出群聊
                    MsgInfo: nick + ",退出聊天室",
                    nick: usenike,
                    Uid: useid,
                    RoomId: 0//群ID
                };
                WEB_SOCKET.send(JSON.stringify(msg));
            });
        })
    </script>
}

中间件主要code

using System.Net.WebSockets;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
namespace WebApp
{
    public class WebSocketHandlerMiddleware : IMiddleware
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            if (context.Request.Path == "/ws")
            {
                if (context.WebSockets.IsWebSocketRequest)
                {
                    try
                    {
                        WebSocket websocket = await context.WebSockets.AcceptWebSocketAsync();
                        if (websocket != null)
                        {
                            var wsclient = new WebSocketClient
                            {
                                Uid = "",// clientId,
                                WebSocket = websocket
                            };
                            await Handle(wsclient);
                        }
                    }
                    catch (Exception ex)
                    {
                        await context.Response.WriteAsync(ex.Message);
                    }
                }
                else
                {
                    context.Response.StatusCode = 404;
                }
            }
            else
            {
                await next(context);
            }
        }

        private async Task Handle(WebSocketClient wsclient)
        {
            WebSocketClientCollection.AddClient(wsclient);

            WebSocketReceiveResult clientData = null;
            do
            {
                var buffer = new byte[1024 * 10];
                clientData = await wsclient.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), CancellationToken.None);
                if (clientData.MessageType == WebSocketMessageType.Text)
                {
                    string msgStr = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                    var useMsg = JsonConvert.DeserializeObject<UseMsg>(msgStr);
                    useMsg.Uid = useMsg.Uid;//这里暂时使用系统的 guid
                    wsclient.Uid = useMsg.Uid;
                    await HandlessMessageAsync(useMsg);//除了具体的消息
                }

            } while (!clientData.CloseStatus.HasValue);
            WebSocketClientCollection.RemoveClient(wsclient.Uid);
            //log一下
        }

        private async Task HandlessMessageAsync(UseMsg useMsg)
        {
            switch (useMsg.Action)
            {
                case 0:; break;
                case 1:; break;
                case 2:; break;
                case 3:; break;
                case 4:; break;
                case 5:; break;
                case 6:; break;
                case 7://加入到房间
                       //写入到用户的房间表中,一个房间一行主数据
                    var client = WebSocketClientCollection.GetCLient(useMsg.Uid);
                    await JoinToRoom(client, useMsg);
                    ; break;
                case 8://单聊

                    //var buffer = new ArraySegment<byte>();
                    //await client.WebSocket.SendAsync(buffer, WebSocketMessageType.Text, WebSocketMessageFlags.EndOfMessage, CancellationToken.None)
                    //    ; break;
                    var receClient = WebSocketClientCollection.GetCLient(useMsg.ToUid.ToString());
                    if (receClient != null)
                    {
                        string msgStr = useMsg.MsgInfo;
                        byte[] by = Encoding.UTF8.GetBytes(msgStr);
                        var buffer = new ArraySegment<byte>(by, 0, by.Length);
                        await receClient.WebSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                    break;

                case 9://群聊
                    var receClients = WebSocketClientCollection.GetAllClient();
                    if (receClients != null)
                    {
                        string msgStr9 = useMsg.MsgInfo;
                        byte[] by9 = Encoding.UTF8.GetBytes(msgStr9);
                        var buffer9 = new ArraySegment<byte>(by9, 0, by9.Length);
                        foreach (var item in receClients)//也可以排除发送者自己
                        {
                            await item.WebSocket.SendAsync(buffer9, WebSocketMessageType.Text, true, CancellationToken.None);
                        }
                    }
                    break;
                case 10://离开聊天室
                    string get_uid = useMsg.Uid.ToString();
                    var receClient10 = WebSocketClientCollection.GetCLient(get_uid);
                    if (receClient10 != null)
                    {
                        //string msgStr10 = useMsg.MsgInfo;
                        //byte[] by10 = Encoding.UTF8.GetBytes(msgStr10);
                        //var buffer10 = new ArraySegment<byte>(by10, 0, by10.Length);
                        //await receClient10.WebSocket.SendAsync(buffer10, WebSocketMessageType.Text, true, CancellationToken.None);
                        WebSocketClientCollection.RemoveClient(receClient10.Uid);
                        
                        await receClient10.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure,string.Empty, CancellationToken.None);
                    }
                    ; break;
                default:
                    break;
            }
        }

        private async Task<bool> JoinToRoom(WebSocketClient client, UseMsg msg)
        {
            string uid = msg.Uid;
            if (client!=null)
                client.Uid = uid;
            if (WebSocketClientCollection.GetCLient(uid) == null)
                WebSocketClientCollection.AddClient(client);
            string msgStr = msg.MsgInfo;
            byte[] by = Encoding.UTF8.GetBytes(msgStr);
            var buffer = new ArraySegment<byte>(by, 0, by.Length);
            //所有人收到消息
            var clients = WebSocketClientCollection.GetAllClient();
            if (clients != null)
            {
                clients = clients.Where(c => !string.IsNullOrEmpty(c.Uid)).ToList();
                foreach (var c in clients)
                {
                    await c.WebSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                }
            }
            return true;
        }
    }
}

入口处相关code

using WebApp;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<WebSocketHandlerMiddleware>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseWebSockets();
app.UseMiddleware<WebSocketHandlerMiddleware>();
app.UseAuthorization();

app.MapControllers();
app.Run();

相关模型实体

namespace WebApp
{
    public class UseMsg
    {
        /// <summary>
        /// 系统当前聊天用户的ID
        /// </summary>
        public string Uid { get; set; }
        /// <summary>
        ///默认:人员ID
        /// </summary>
        public int ToUid { get; set; }
        /// <summary>
        ///当前 选择群或者叫房间的ID
        /// </summary>
        public int RoomId { get; set; }
        /// <summary>
        /// 消息类型,默认0:文字,1:图片,2:视频;3:音频;4:震动;5:离线消息;6:系统表情包(如图片,gif等);7:加入聊天室;8:单聊;9:群聊;10:离开
        /// </summary>
        public int Action { get; set; }
        public string MsgInfo { get; set; }

    }
}
using System.Net.WebSockets;

namespace WebApp
{
    public class WebSocketClient
    {
        public string Uid { get; set; }
        /// <summary>
        /// 当时链接的socket
        /// </summary>
        public WebSocket WebSocket { get; set; }
    }
}
using System.Linq;

namespace WebApp
{
    public class WebSocketClientCollection
    {
        private static List<WebSocketClient> _client = new List<WebSocketClient>();

        public static void AddClient(WebSocketClient client)
        {
            var clientNow = _client.Where(c => c.Uid == client.Uid).FirstOrDefault();
            if (clientNow != null)
                _client.Remove(client);
            _client.Add(client);
        }

        public static void RemoveClient(string clientId)
        {
            var clientNow = _client.Where(c => c.Uid == clientId).FirstOrDefault();
            if (clientNow != null)
                _client.Remove(clientNow);
        }

        public static WebSocketClient GetCLient(string clientId)
        {
            return _client.FirstOrDefault(c => c.Uid == clientId);
        }
        public static List<WebSocketClient> GetAllClient()
        {
            return _client;
        }
        //public static List<WebSocketClient> GetAllGroupClient(List<int> groupIds)
        //{
        //    var clientsNow = _client.Where(c =>c.ro);
        //    return clientsNow;
        //}

    }

}

最后附上测试效果

  到此先告一个段落

 

橙子主题打折出售

其实我不卖,主要是这里是放广告的,所以就放了一个
毕竟主题都没做完,卖了也是坑.

购买它
本文为原创文章,请注意保留出处!

热门文章

SharePoint2010升级到SharePoint2013操作手册 SharePoint2010升级到SharePoint2013操作手册目录第一章...SharePoint2010升级到SharePoint2013操作手册 作者:Pastore Antonio
1700 浏览量
C# DataTable 某一列求和 列为数字类型doubletotal=Convert.ToDouble(datatable.Com...C#DataTable某一列求和 作者:Pastore Antonio
1673 浏览量
修复moss本机访问SharePoint 401.1 HTTP错误 环境:DCServer&...修复moss本机访问SharePoint401.1HTTP错误 作者:Pastore Antonio
1661 浏览量
从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 这一篇是从0开始搭建SQLServerAlwaysOn的第三篇,这一篇才真正开始搭建Alway...从0开始搭建SQLServerAlwaysOn第三篇(配置AlwaysOn) 作者:Pastore Antonio
1627 浏览量
SharePoint REST API – 概述 博客地址:http://blog.csdn.net/FoxDaveSharePointRES...SharePointRESTAPI–概述 作者:Pastore Antonio
1616 浏览量
Adding Docker Repository to CentOS 在CentOS系统上添加Docker官方仓库是安装和管理Docker的第一步。以下是详细...AddingDockerRepositorytoCentOS 2026-02-14 · Xzavier Aaron
Flowise 前端框架配置指南 用户需求问题:有没有适合配置Flowise的前端框架?目标:寻找类似OpenWebUI...Flowise前端框架配置指南 2026-02-14 · Xzavier Aaron
aspnet-wwwroot-error-solution ASP.NETCore启动报错:DirectoryNotFoundExceptionwwwroo...aspnet-wwwroot-error-solution 2025-12-28 · Pastore Antonio
SharePoint Server 出现 ERR_HTTP2_PROTOCOL_ERROR 如果SharePointServer在http的情况下能够访问,但是在https下不能访问报错如...SharePointServer出现ERR_HTTP2_PROTOCOL_ERROR 2025-10-21 · Pastore Antonio
.NET CORE 快速文本搜索器 简单的搜索引擎:usingSystem;usingSystem.Collections.Gen....NETCORE快速文本搜索器 2025-09-25 · Pastore Antonio
Sql Server 部署SSIS包完成远程数据传输 简介与背景在现代数据管理中,如何高效地完成远程数据的更新任务一直是一个重要的挑战。本文的背景起源于...SqlServer部署SSIS包完成远程数据传输 2026-02-14 · Xzavier Aaron
Coolify的使用 简介Coolify是一种功能强大的自托管综合解决方案,旨在简化应用、数据库以及开源服务的托管流程。...Coolify的使用 2026-02-14 · Xzavier Aaron
Coolify的使用 简介Coolify是一种功能强大的自我托管解决方案,专为那些希望掌控自己的应用、数据库以及开源服...Coolify的使用 2026-02-14 · Xzavier Aaron
SharePoint 2019 Web Application Creation 在SharePoint2019中创建WebApplication,可以使用PowerSh...SharePoint2019WebApplicationCreation 2026-02-14 · Xzavier Aaron
vscode使用sftp上传 简介在现代开发环境中,VSCode凭借其强大的扩展性和丰富的功能,成为许多开发者的首选代码编辑器。...vscode使用sftp上传 2026-02-14 · Xzavier Aaron
在现有Seafile 上追加 Azure Blob 磁盘 已有运行中的Seafile(Docker)现有数据保持不变新增几个AzureBlob作为...在现有Seafile上追加AzureBlob磁盘 2025-11-21 · Pastore Antonio
.NET CORE 传统方式调用SharePoint 直接贴代码:usingMicrosoft.SharePoint.Client;usingPnP....NETCORE传统方式调用SharePoint 2025-09-25 · Pastore Antonio
Azure 申请SharePoint 应用 登录后台如下:进入Azure:选择之后进入创建应用:进入之后输入名字按照如下图示点击注册:创...Azure申请SharePoint应用 2025-09-25 · Pastore Antonio
VS中MVC解决方案复制后修改调试端口 我之前是直接去解决方案属性中修改:然后恭喜你,你会喜提报错。正确方式,打开项目属性:这里重置切...VS中MVC解决方案复制后修改调试端口 2025-03-17 · Pastore Antonio
如何在C#WinForms应用程序中显示当前版本信息 在开发C#WinForms应用程序时,向用户展示当前版本信息是一个常见的需求。这不仅可以帮助用户了解...如何在C#WinForms应用程序中显示当前版本信息 2025-03-10 · Pastore Antonio
2022年4月30日 削苹果削了手,太懒不想收藏资料的时候复制粘贴所以开发了一个快速发布的组件。花了2天……浏览量:1...2022年4月30日 2022-04-30 · Pastore Antonio
2021年12月27日 头疼/胸闷/肋条疼/脚脖子疼……没钱……明天要给员工发工资了。浏览量:1,825 2021-12-27 · Pastore Antonio
2021年12月22日 今天天气:多云转晴早上太多雾,但怕迟到还是一路超速……赶到了目的地,在车库绕了四层没一个车位,绕晕...2021年12月22日 2021-12-22 · Pastore Antonio
aspnet-wwwroot-error-solution ASP.NETCore启动报错:DirectoryNotFoundExceptionwwwroo...aspnet-wwwroot-error-solution 2025-12-28 · Pastore Antonio
SharePoint Server 出现 ERR_HTTP2_PROTOCOL_ERROR 如果SharePointServer在http的情况下能够访问,但是在https下不能访问报错如...SharePointServer出现ERR_HTTP2_PROTOCOL_ERROR 2025-10-21 · Pastore Antonio
.NET CORE 快速文本搜索器 简单的搜索引擎:usingSystem;usingSystem.Collections.Gen....NETCORE快速文本搜索器 2025-09-25 · Pastore Antonio
.NET CORE 传统方式调用SharePoint 直接贴代码:usingMicrosoft.SharePoint.Client;usingPnP....NETCORE传统方式调用SharePoint 2025-09-25 · Pastore Antonio
Azure 申请SharePoint 应用 登录后台如下:进入Azure:选择之后进入创建应用:进入之后输入名字按照如下图示点击注册:创...Azure申请SharePoint应用 2025-09-25 · Pastore Antonio
.NET CORE 传统方式调用SharePoint 直接贴代码:usingMicrosoft.SharePoint.Client;usingPnP....NETCORE传统方式调用SharePoint 2025-09-25 · Pastore Antonio
Azure 申请SharePoint 应用 登录后台如下:进入Azure:选择之后进入创建应用:进入之后输入名字按照如下图示点击注册:创...Azure申请SharePoint应用 2025-09-25 · Pastore Antonio
.NET CORE 使用应用方案操作SharePoint Online 世纪互联版 我来为你创建一个.NETCore应用程序,用于向世纪互联SharePointOnline....NETCORE使用应用方案操作SharePointOnline世纪互联版 2025-09-25 · Pastore Antonio
Microsoft Excel 365 的 DCOMCNFG 中缺少 Microsoft Excel 应用程序 试试这个方法:这个方法不是解决你看不看得到,而是配置你看不到也能使用了。原操作方案:Micro...MicrosoftExcel365的DCOMCNFG中缺少MicrosoftExcel应用程序 2025-06-11 · Pastore Antonio
使用SPFX开发SharePoint SE\2019过程中的问题 遇到不能新建ListView控件的,不要怀疑重装就行。装好了去看:C:\Users\Adminis...使用SPFX开发SharePointSE\2019过程中的问题 2025-06-10 · Pastore Antonio
为你的wordpress主题添加支持文章格式 如果你的主题不支持文章格式,首先你需要在functions.php中添加如下类似代码让你的主题支持该...为你的wordpress主题添加支持文章格式 2024-04-17 · Pastore Antonio
wordpress新增文章类型 要在WordPress中添加自定义文章类型,您可以按照以下步骤进行:使用函数创建自定义文章类型:...wordpress新增文章类型 2024-04-17 · Pastore Antonio
去除WordPress登录页面的翻译组件 在主题function.php中添加如下内容:add_filter(‘login_d...去除WordPress登录页面的翻译组件 2023-08-30 · Pastore Antonio
Linux 下Wordpress博客搭建 WordPress#下载安装文件cd/usr/local/nginx/html/blogw...Linux下WordPress博客搭建 2021-12-11 · Pastore Antonio
从零开始在linux下搭建wordpress博客 一,准备linux环境本地虚拟机可以忽略第一部分微博以及微信的公共平台现在正火的一塌糊涂。既...从零开始在linux下搭建wordpress博客 2021-12-11 · Pastore Antonio
centos 常见问题 1:DNS配置域名无法在Linux下解析是一个比较普遍的问题,造成这个问题有很多原因,比如:服务器...centos常见问题 2023-11-08 · Pastore Antonio
linux中查找包含指定内容的文件 文件名+内容根据时间查找日志查询指定时间段内的日志查找关键字只显示包含内容的文件名文件名+...linux中查找包含指定内容的文件 2021-12-11 · Pastore Antonio
Linux 下Wordpress博客搭建 WordPress#下载安装文件cd/usr/local/nginx/html/blogw...Linux下WordPress博客搭建 2021-12-11 · Pastore Antonio
从零开始在linux下搭建wordpress博客 一,准备linux环境本地虚拟机可以忽略第一部分微博以及微信的公共平台现在正火的一塌糊涂。既...从零开始在linux下搭建wordpress博客 2021-12-11 · Pastore Antonio
linux 安装php8 准备工作  创建空文件夹>mkdir/opt/php//创建目录>cd/...linux安装php8 2021-12-11 · Pastore Antonio

最新发布

Sql Server 部署SSIS包完成远程数据传输 简介与背景在现代数据管理中,如何高效地完成远程数据的更新任务一直是一个重要的挑战。本文的背景起源于...SqlServer部署SSIS包完成远程数据传输 转载 2026-02-14
Coolify的使用 简介Coolify是一种功能强大的自托管综合解决方案,旨在简化应用、数据库以及开源服务的托管流程。...Coolify的使用 转载 2026-02-14
Coolify的使用 简介Coolify是一种功能强大的自我托管解决方案,专为那些希望掌控自己的应用、数据库以及开源服...Coolify的使用 转载 2026-02-14
SharePoint 2019 Web Application Creation 在SharePoint2019中创建WebApplication,可以使用PowerSh...SharePoint2019WebApplicationCreation 转载 2026-02-14
vscode使用sftp上传 简介在现代开发环境中,VSCode凭借其强大的扩展性和丰富的功能,成为许多开发者的首选代码编辑器。...vscode使用sftp上传 转载 2026-02-14
aspnet-wwwroot-error-solution ASP.NETCore启动报错:DirectoryNotFoundExceptionwwwroo...aspnet-wwwroot-error-solution #C# 2025-12-28
SharePoint Server 出现 ERR_HTTP2_PROTOCOL_ERROR 如果SharePointServer在http的情况下能够访问,但是在https下不能访问报错如...SharePointServer出现ERR_HTTP2_PROTOCOL_ERROR #C# 2025-10-21
.NET CORE 快速文本搜索器 简单的搜索引擎:usingSystem;usingSystem.Collections.Gen....NETCORE快速文本搜索器 #C# 2025-09-25
.NET CORE 传统方式调用SharePoint 直接贴代码:usingMicrosoft.SharePoint.Client;usingPnP....NETCORE传统方式调用SharePoint #C# 2025-09-25
Azure 申请SharePoint 应用 登录后台如下:进入Azure:选择之后进入创建应用:进入之后输入名字按照如下图示点击注册:创...Azure申请SharePoint应用 #C# 2025-09-25