日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core 快速入门(实战篇)

發布時間:2023/12/4 asp.net 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core 快速入门(实战篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上篇講了《asp.net core在linux上的環境部署》。今天我們將做幾個小玩意實戰一下。用到的技術和工具有mysql、websocket、AngleSharp(爬蟲html解析)、nginx多站點部署。

NO1 留言板(mysql的使用)

演示:http://haojima.net
這個功能很簡單。就是對數據庫的寫入和展示。如果在Windows下,相信大家分分鐘都可以搞定。而初次接觸.net core + mysql可能需要注意些細節。
首先打開vs2017新建一個asp.net core項目(選Web應用程序),然后nuget 導入Microsoft.EntityFrameworkCore.Tools 1.1.1和MySql.Data.EntityFrameworkCore 8.0.8-dmr。
然后新建一個DbContext類。

public class DataContext : DbContext{ ? ?//【注意】連接字符串一定要加 sslmode=none
?string str = @"Data Source=;Database=;User ID=;Password=;pooling=true;CharSet=utf8;port=3306;sslmode=none"; ? ?protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>optionsBuilder.UseMySQL(str); ?
?//下面就可以添加要加入數據庫的實體了//public DbSet<Message> Messages { get; set; }}

到此為止,我們已經可以利用EF Core直接連接mysql進行增刪改查操作了。注意:需要導入命名空間using Microsoft.EntityFrameworkCore; using MySQL.Data.EntityFrameworkCore.Extensions;

當然。你會說,連接字符串不能硬編碼到代碼里面。我們也可以放配置文件。appsettings.json

{"Logging": {"IncludeScopes": false,"LogLevel": {"Default": "Warning"}},"ConnectionStrings": { "SqlServerConnection": "Data Source=;Database=;User ID=;Password=;pooling=true;CharSet=utf8;port=3306;sslmode=none" } }

然后把上面的硬編碼注釋掉。在Startup.cs文件的ConfigureServices方法添加

var connection = Configuration.GetConnectionString("SqlServerConnection"); services.AddDbContext<DataContext>(options => options.UseMySQL(connection));

【注意】項目名稱和路徑最好不要有中文,不然會出現些亂七八糟的問題。

【完整代碼】:https://github.com/zhaopeiym/BlogDemoCode/tree/master/MessageBoard

NO2 聊天室(WebSocket的使用)

演示:http://socket.haojima.net
WebSocket是Html5新增的一個很酷的技術。下面我們簡單講解下這個很酷的技術

var Socket = new WebSocket(url);//創建 WebSocket 對象

創建了一個WebSocket對象后會觸發打開連接事件:

Socket.onopen = function(){ ?}

除了onopen事件,還有其他三個事件:

Socket.onmessage ?//客戶端接收服務端數據時觸發Socket.onerror ? ?//通信發生錯誤時觸發Socket.onclose ? ?//連接關閉時觸發

另外還有兩個方法:

Socket.send() ? //使用連接發送數據Socket.close() ?//關閉連接

最后還有四個連接狀態屬性:

Socket.readyState0 - 表示連接尚未建立。 1 - 表示連接已建立,可以進行通信。 2 - 表示連接正在進行關閉。 3 - 表示連接已經關閉或者連接不能打開。

整個WebSocket常用功能知識點就四個事件、兩個方法、四種狀態。簡單吧,下面我們看看asp.net core后臺的配合:

后臺添加一個SocketHandler類,并添加一個靜態方法Map:

/// <summary>/// 請求/// </summary>/// <param name="app"></param>public static void Map(IApplicationBuilder app){app.UseWebSockets(); //【注意】需要 nuget ? 導入 Microsoft.AspNetCore.WebSockets.Serverapp.Use(Acceptor); }

然后新增對應的Acceptor方法:

/// <summary>
/// 接收請求
/// </summary>
/// <param name="httpContext"></param>
/// <param name="n"></param>/// <returns></returns>static async Task Acceptor(HttpContext httpContext, Func<Task> n){

需要在Startup.cs類里面的Configure方法里面加入

app.Map("/ws", SocketHandler.Map); ? //傳入我們剛才新建的靜態方法Map

現在為止,基本的類和配置已經完成。
我們主要操作,是在Acceptor方法里面接收和發送消息。

//建立連接var socket = await httpContext.WebSockets.AcceptWebSocketAsync();//等待接收數據await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);//發送消息await socket.SendAsync(arraySegment, WebSocketMessageType.Text, true, CancellationToken.None);

后臺關鍵代碼也就這三句,建立連接、等待接收、發送消息。
不過這里有一點需要理解。建立連接后,可以接收任意多次客戶端消息。所以ReceiveAsync等待接收這里需要死循環接收消息,直到連接斷開。(不用擔心真的死循環,沒有消息發送的時候,代碼會阻塞在那里等待消息)

【完整實現】:https://github.com/zhaopeiym/ChatRoom

NO3 找工作(AngleSharp的使用)

演示:http://job.haojima.net
對于爬蟲抓包,我相信大家初次接觸都非常的熱衷于此。我也不例外。
那么在asp.net core下面是否也有這樣的插件呢?答案是肯定的。
http://www.cnblogs.com/linezero/p/5599611.html?HtmlAgilityPack HTML解析(感謝博主對.net core的貢獻)。不過xpath用起來超級惡心。
之前在.net下面有一款Jumony?http://www.cnblogs.com/Ivony/p/3447536.html(博客園大牛寫的)。支持CSS選擇和linq查詢。簡直不要太爽。可是不支持.net core。(本人試了下遷移.net core,發現很多類在.net core沒有實現)
最后還是到了一款支持.net core的解析組件。并可以媲美Jumony,同樣支持css選擇和linq查詢。那就是AngleSharp。
新建項目,nuget 安裝 AngleSharp。然后以下簡單使用:

using (HttpClient http = new HttpClient()) { ?
?var htmlString = await http.GetStringAsync(url); ?
??HtmlParser htmlParser = new HtmlParser();
?? ?var jobInfos = htmlParser.Parse(htmlString).QuerySelectorAll(".newlist_list_content table").Where(t => t.QuerySelectorAll(".zwmc a").FirstOrDefault() != null).Select(t => new JobInfo(){PositionName = t.QuerySelectorAll(".zwmc a").FirstOrDefault().TextContent,CorporateName = t.QuerySelectorAll(".gsmc a").FirstOrDefault().TextContent,Salary = t.QuerySelectorAll(".zwyx").FirstOrDefault().TextContent,WorkingPlace = t.QuerySelectorAll(".gzdd").FirstOrDefault().TextContent,.ToList(); ?
?? ? ?return jobInfos; }

看到沒有,就像jq一樣解析html。如果你說不爽我都不信。

【完整實現】:https://github.com/zhaopeiym/JobWanted

部署多個站點

以上,這些項目都比較簡單。關鍵技術點和難點都進行的分析。我相信大家都可以動起手練習起來了。
不過有個問題,前面我們只說了部署一個應用程序。如果是多個該怎么部署呢?
首先我們把多個程序發布包放到服務器上。
然后修改nginx的配置文件/etc/nginx/conf.d/default.conf

server { ?
?listen 80; ?
? ?server_name www.haojima.net; ?
? ?? ? ? ? #對應的域名root /home/projects/messagBoard; ?
? ?? ? ? ? ? ? #程序路徑location / { ? ? ?
? ?? ? ? ? ? ? ?proxy_pass http://localhost:5000; ?#內網端口
? ? ? ?proxy_http_version 1.1;
? ?? ? ? ? ? ? ?proxy_set_header Upgrade $http_upgrade; ? ?
? ?? ? ? ? ? ? ?proxy_set_header Connection keep-alive; ? ?
? ?? ? ? ? ? ? ?proxy_set_header Host $host; ? ? ?
? ?? ? ? ? ? ? ?proxy_cache_bypass $http_upgrade; ?
? ?? ? ? ? ? ? ?proxy_set_header X-real-ip $remote_addr; ? ?? ??
? ?? ? ? ? ? ? ?proxy_set_header Upgrade $http_upgrade; ? } }

有幾個程序就添加幾個server,不過需要修改你解析到的域名、程序路徑和內網對應的端口(看配置里的注釋) 。
然后修改supervisor的配置文件/etc/supervisor/conf.d/supervisord.conf

[program:MessageBoard]command=dotnet MessageBoard.dll ? ? ? ?; 運行程序的命令directory= /home/projects/messagBoard/ ; 命令執行的目錄autorestart=true ? ? ? ? ? ? ? ? ? ?; 程序意外退出是否自動重啟stderr_logfile=/var/log/WebApplication1.err.log ; 錯誤日志文件stdout_logfile=/var/log/WebApplication1.out.log ; 輸出日志文件environment=ASPNETCORE_ENVIRONMENT=Production ; 進程環境變量user=root ; 進程執行的用戶身份stopsignal=INT

有幾個程序就往下復制幾份program。需要修改program名稱,只要名稱不重復就可以。然后修改 運行程序的命令 對應的dll和命令執行的目錄(看配置文件的注釋)。
如此就可以部署多個程序了。

開始我還以為是在域名解析的時候,解析IP + 端口。原來是多個域名解析到同一個IP,然后nginx在內部做域名和內網端口分發。

一些其它的細節

部署阿里云

我們在linux的防火墻開放了端口,發現在外面還是訪問不了(可以telnet IP 端口 來測試)。有可能是阿里云攔截了。https://help.aliyun.com/document_detail/25471.html?在安全組添加某端口哪些IP可以訪問。

mysql的客戶端

對于mysql,我們安裝好之后總不能每次命令操作吧。在Windows下面有個客戶端Navicat可以方便管理mysql。Navicat

獲取ip

用了nginx后發現取不到瀏覽器IP了。那是因為我們程序都是瀏覽器訪問nginx,然后nginx轉發內網程序端口。所以取到的IP都是內網本機IP。如果需要取瀏覽器IP需要在nginx配置

server { ? ?
listen 80; ?
?server_name www.haojima.net; ?
? ?root /home/projects/messagBoard; ?
? ? ?location / { ? ? ?
? ? ??proxy_pass http://localhost:5000;
? ? ??? ? ? ?proxy_http_version 1.1; ?? ? ?
? ? ??? ? ? ?proxy_set_header Upgrade $http_upgrade; ?
? ? ??? ? ? ??proxy_set_header Connection keep-alive; ?
? ? ??? ? ? ??proxy_set_header Host $host; ? ?
? ? ??? ? ? ??proxy_cache_bypass $http_upgrade; ?
? ? ??? ? ? ??proxy_set_header X-real-ip $remote_addr; ? ? # 新添加} }

然后代碼里面取IP:

var ip = HttpContext.Request.Headers["X-real-ip"].FirstOrDefault();

WebSocket在nginx的配置

上面我們寫的WebSocket直接運行發現沒有任何問題,可是部署在nginx去跑不起來了。那是因為需要nginx支持WebSocket,需要配置。http://nginx.org/en/docs/http/websocket.html

server { ?
?listen 80; ?
??server_name job.haojima.net;
??? ?root /home/projects/jobWanted; ?
??? ??location / { ? ? ?
??? ???proxy_pass http://localhost:5002; ?
??? ???proxy_http_version 1.1; ? ?
??? ???proxy_set_header Upgrade $http_upgrade; ?
??? ???proxy_set_header Connection keep-alive;
??? ???proxy_set_header Host $host;
??? ???proxy_cache_bypass $http_upgrade;
??? ???proxy_set_header X-real-ip $remote_addr; ?
??? ???proxy_set_header Upgrade $http_upgrade;
??? ???# 新增proxy_set_header Connection "upgrade"; ? ? ?# 新增 } }

WebSocket心跳

經過上面的配置,我們的WebSocket在nginx上跑起來了。萬分歡喜的我們,發現一分鐘不發消息就自動掉線了。郁悶至極到頭大。細心的同學通過上面的鏈接資料其實已經有說明:

By default, the connection will be closed
if the proxied server does not transmit any data within 60 seconds. This timeout can be increased with the proxy_read_timeout directive. Alternatively, the proxied server can be configured to periodically send WebSocket ping frames to reset the timeout and check if the connection is still alive.

靠,英文實在太爛了。

默認情況下,如果代理的服務器在60秒內沒有傳輸任何數據,則連接將被關閉。可以使用proxy_read_timeout指令增加此超時 。或者,代理服務器可以配置為定期發送WebSocket ping幀以重置超時并檢查連接是否仍然存在。

nginx給出了兩種解決方案。第一種,修改proxy_read_timeout (默認60秒)。第二種,瀏覽器客戶端定時發送心跳包(時間要短于proxy_read_timeout)。
我使用的是第二種方式。
第一種雖然簡單粗暴,但是時間再長也是一個值,還是會有超時的可能。再者,誰能保證瀏覽器端不會new 很多個WebSocket出來搗蛋。
第二種方式,瀏覽器定時發送一條消息,內容和后臺約定下。如發送“心跳”,然后后臺接收消息是,判斷如果是“心跳”則不做任何處理。

中文編碼

在做“找工作”爬前程無憂的數據時,發現他們使用的GBK編碼。而在.net core中默認不支持這種格式,導致取到的數據都是亂碼。我們需要nuget安裝System.Text.Encoding.CodePages。然后在Startup.cs的Configure里面注冊:

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);//注冊編碼提供程序

使用:

var htmlBytes = await http.GetByteArrayAsync(url);
var htmlString = Encoding.GetEncoding("GBK").GetString(htmlBytes);

asp.net core 端口分配

asp.net core 默認端口都是5000。那么我們運行第二個程序的時候就會提示5000端口被占用。這個時候,我們就需要為每個程序分配不同的端口了。
在根目錄新建一個json文件hosting.json

{"server.urls": "http://*:5002"}

在Program.cs文件修改

public static void Main(string[] args){
? ?var config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("hosting.json", optional: true).Build(); ? ?var host = new WebHostBuilder().UseKestrel().UseConfiguration(config).UseContentRoot(Directory.GetCurrentDirectory()).UseIISIntegration().UseStartup<Startup>().UseApplicationInsights().Build();host.Run(); }

爬拉勾數據

在爬拉勾網的時候沒有搞定,不知道是不是因為https的原因。

using (HttpClient http = new HttpClient()) { ? ?var url = "https://www.lagou.com/zhaopin/Java/?labelWords=label"; ? ?var htmlString = await http.GetStringAsync(url); }

在.net core中報錯:An unhandled exception occurred while processing the request.
在.net 4.5 中抓到的數據是“頁面加載中...”。和瀏覽器訪問的結果不一樣。
原因未知。如果有大佬解惑,感激不盡!

?

參考
http://www.runoob.com/html/html5-websocket.html
http://www.cnblogs.com/liguobao/p/6130121.html
http://www.cnblogs.com/linezero/p/5806814.html
演示
http://haojima.net
http://socket.haojima.net
http://job.haojima.net
源碼
https://github.com/zhaopeiym/JobWanted
https://github.com/zhaopeiym/ChatRoom
https://github.com/zhaopeiym/BlogDemoCode

原文地址:http://www.cnblogs.com/zhaopei/p/netcore2.html


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的ASP.NET Core 快速入门(实战篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。