ASP.Net最小Web API
最近需要搭建一个Windows Web服务器,处理一些很简单的访问请求,于是研究了一下ASP.Net的最小Web API
项目创建
打开VS2022,按照ASP.Net模块后,使用模板创建项目
程序运行
模板是一个预测(随机生成)未来五天天气的demo,可以用命令行启动程序
dotnet run --project=./项目名称
|
Mini API
模板项目内容非常少,只有一个C#文件
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/weatherforecast", () => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( ... )) .ToArray(); return forecast; });
app.Run();
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); }
|
record可以用于快速定义一个类
record EditTodoItemRequest(int Id, TodoItemDTO Dto, TodoDb Db);
class EditTodoItemRequest { public int Id { get; set; } public TodoItemDTO Dto { get; set; } = default!; public TodoDb Db { get; set; } = default!; }
|
添加一个新Get
app.MapGet("/open/{path}", (string path) => { try { Process.Start("explorer.exe", path); } catch (Exception ex) { Console.WriteLine($"Can't open folder: {ex.Message}"); } });
|
用文件浏览器打开本地的C:\Users\28240\code
路径
解析Request内容
app.MapGet("/do", (HttpRequest request) => { var prop_a = request.Query["a"]; var prop_b = request.Query["b"]; var sessionid = request.Query["sessionid"]; });
|
输入一个文件
app.MapPost("/do", (HttpRequest request) => { var sourceFile = request.Form.Files[0]; using (var st = new FileStream(localPath, FileMode.Create)) { sourceFile.CopyTo(st); } ... });
|
返回一个文件
app.MapPost("/download", (HttpRequest request) => { return Results.File(System.IO.File.OpenRead(localVideoPath), "video/mp4"); });
|
用python下载这个文件
response = requests.post(url, headers=headers, files={"file": file}) if response.status_code == 200: print("Request successful!") with open('received_file.mp4', 'wb') as f: f.write(response.content) print("文件已保存为 'received_file.mp4'") else: print("Request failed with status code:", response.status_code)
|
url转义规则
除了下面这些保留字外,用%{两位十六进制}
进行转义
字符 |
转义形式 |
空格 |
%20 |
! |
%21 |
* |
%2A |
’ |
%27 |
( |
%28 |
) |
%29 |
; |
%3B |
: |
%3A |
@ |
%40 |
& |
%26 |
= |
%3D |
+ |
%2B |
$ |
%24 |
, |
%2C |
/ |
%2F |
? |
%3F |
# |
%23 |
[ |
%5B |
] |
%5D |
Web Socket
除了简单的Web API,我们有时也会用到Web Socket
服务端代码
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
var webSocketOptions = new WebSocketOptions { KeepAliveInterval = TimeSpan.FromMinutes(2) };
app.UseWebSockets(webSocketOptions);
app.MapControllers();
app.Run();
|
namespace SocketDemo.Controllers { public class xxxxController : ControllerBase { [Route("/ws")] public async Task Get() { if (HttpContext.WebSockets.IsWebSocketRequest) { using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); await Echo(webSocket); } else { HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; } }
private static async Task Echo(WebSocket webSocket) { Console.WriteLine("First Connect"); var buffer = new byte[1024 * 4]; var receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None);
while (!receiveResult.CloseStatus.HasValue) { var segment = new ArraySegment<byte>(buffer, 0, receiveResult.Count); await webSocket.SendAsync( segment, receiveResult.MessageType, receiveResult.EndOfMessage, CancellationToken.None); Console.WriteLine($"Send: {Encoding.UTF8.GetString(segment.Array, segment.Offset, segment.Count)}");
receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None); }
await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None); } } }
|
客户端代码
import asyncio import websockets
async def connect_to_server(): uri = "wss://localhost:7167/ws"
async with websockets.connect(uri) as websocket: print(f"Connected to {uri}")
try: while True: message = input("Enter message to send (or 'exit' to quit): ")
if message.lower() == "exit": break
await websocket.send(message) print(f"> Sent: {message}")
response = await websocket.recv() print(f"< Received: {response}")
finally: await websocket.close() print("WebSocket connection closed")
asyncio.run(connect_to_server())
|
注:客户端连接websocket时,不使用http、https,而是ws、wss