概述
这里可以和JAVA中的路径映射进行对应,将对应的HTTP请求和要执行的方法进行映射。
使用方式如下:
Map(),MapGet(),MapPost()
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
//enable routing
app.UseRouting();
app.UseEndpoints(endpoints =>{
//add your endpoints
endpoints.Map("/map1",async (context) =>
{
await context.Response.WriteAsync("in map 1");
});
endpoints.MapPost("/map2", async (context) =>
{
await context.Response.WriteAsync("in map 2");
});
endpoints.MapGet("/map3", async (context) =>
{
await context.Response.WriteAsync("in map 3");
});
});
app.Run(async context =>
{
await context.Response.WriteAsync($"Request received at{context.Request.Path}");
});
app.Run();
当请求路径与设定的URL相同时,Map()方法可以接收到Get和Post请求方法,但是MapGet()只能接收到get请求方法,同理,MapPost()只能接收post请求方法。
GetEndpoint
只有在使用了UseRouting()方法之后,GetEndPoint()才会有对象,EndPoint对象中包含了DisplayName,也就是URL,RequestDelegate是要执行的EndPoint方法。
using Microsoft.AspNetCore.Http;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Use(async (context, next) =>
{
Endpoint? endpoint = context.GetEndpoint(); //得到的是null
if(endpoint != null)
{
await context.Response.WriteAsync($"Endpoint: " +
$"{endpoint.DisplayName}\n");
}
await next(context);
});
//enable routing
app.UseRouting();
app.Use(async (context, next) =>
{
Endpoint? endpoint = context.GetEndpoint();
if (endpoint != null)
{
await context.Response.WriteAsync($"Endpoint: " +
$"{endpoint.DisplayName}\n");
//URL中请求map1, 得到的输出是:
//Endpoint: /map1
//in map 1
}
await next(context);
});
app.UseEndpoints(endpoints =>{
//add your endpoints
endpoints.Map("/map1",async (context) =>
{
await context.Response.WriteAsync("in map 1");
});
endpoints.MapPost("/map2", async (context) =>
{
await context.Response.WriteAsync("in map 2");
});
endpoints.MapGet("/map3", async (context) =>
{
await context.Response.WriteAsync("in map 3");
});
});
app.Run(async context =>
{
await context.Response.WriteAsync($"Request received at{context.Request.Path}");
});
app.Run();
请求路径参数
真实请求路径如下:
/files/sample.txt
/employee/profile/john
在请求路径中,有一些部分是fixed 不变的,可变的部分我们称为路径参数,因此,上边请求路径可以改写为:
/files/{filename}.{extention}
/employee/profile/{employeeName}
代码中可以这样写
using Microsoft.AspNetCore.Http;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
//enable routing
app.UseRouting();
//creating endpoints
app.UseEndpoints(endpoints =>
{
//add your endpoints
endpoints.Map("file/{filename}.{extention}", async context =>
{
string? fileName = Convert.ToString(context.Request.RouteValues["filename"]);
string? extention = Convert.ToString(context.Request.RouteValues["extention"]);
await context.Response.WriteAsync($"In file:{fileName}-{extention}");
});
//给默认值
endpoints.Map("employee/profile/{employeeName=harsha}", async context =>
{
string? employeeName = Convert.ToString(context.Request.RouteValues["employeeName"]);
await context.Response.WriteAsync($"employeeName: {employeeName}");
});
//id项可有可无
endpoints.Map("products/details/{id?}", async context =>
{
if (context.Request.RouteValues.ContainsKey("id"))
{
int? id = Convert.ToInt32(context.Request.RouteValues["id"]);
await context.Response.WriteAsync($"products details -: {id}");
}
else
{
await context.Response.WriteAsync($"products details -: id is not supplied");
}
});
});
app.Run(async context =>
{
await context.Response.WriteAsync($"Request received at{context.Request.Path}");
});
app.Run();
如果想要给默认值,参考代码中profile那一行,如果参数可以有,也可以没有,参考product那一行。
请求路径参数的一些限制
例如 id值我们只想要接收int类型;employeeName我们只想要接收string类型。请求路径后边加上类型限制。
代码示例
using Microsoft.AspNetCore.Http;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
//enable routing
app.UseRouting();
//creating endpoints
app.UseEndpoints(endpoints =>
{
//add your endpoints
endpoints.Map("file/{filename}.{extention}", async context =>
{
string? fileName = Convert.ToString(context.Request.RouteValues["filename"]);
string? extention = Convert.ToString(context.Request.RouteValues["extention"]);
await context.Response.WriteAsync($"In file:{fileName}-{extention}");
});
endpoints.Map("employee/profile/{employeeName:length(4,7)=harsha}", async context =>
{
string? employeeName = Convert.ToString(context.Request.RouteValues["employeeName"]);
await context.Response.WriteAsync($"employeeName: {employeeName}");
});
endpoints.Map("products/details/{id:int:range(1,1000)?}", async context =>
{
if (context.Request.RouteValues.ContainsKey("id"))
{
int? id = Convert.ToInt32(context.Request.RouteValues["id"]);
await context.Response.WriteAsync($"products details -: {id}");
}
else
{
await context.Response.WriteAsync($"products details -: id is not supplied");
}
});
endpoints.Map("/daily-digest-report/{reportdate:datetime}", async context =>
{
DateTime reportDate = Convert.ToDateTime(context.Request.RouteValues["reportdate"]);
await context.Response.WriteAsync($"dateTime - {reportDate}");
});
endpoints.Map("/cities/{cityid:guid}", async context =>
{
Guid cityid = Guid.Parse(Convert.ToString(context.Request.RouteValues["cityid"])!);
await context.Response.WriteAsync($"cityId - {cityid}");
});
endpoints.Map("sales-report/{year:int:min(1900)}/month:regex(^(apr|jul|oct|jan)$)", async context =>
{
int year = Convert.ToInt32(context.Request.RouteValues["year"]);
string? month = Convert.ToString(context.Request.RouteValues["month"]);
await context.Response.WriteAsync($"sales report - {year} - {month}");
});
});
app.Run(async context =>
{
await context.Response.WriteAsync($"Request received at{context.Request.Path}");
});
app.Run();
在真实工程项目中,可以不适用参数限制,对于输错的信息,可以给用户提示输入的信息是错误的。
当一个限制条件在项目中被多次使用,可以创建一个类。
- 创建类
using System.Text.RegularExpressions;
namespace RoutingExample.customConstraint
{
//sales-report/2020/apr
public class MonthCustomConstraint : IRouteConstraint
{
public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
//check whether the value exists
if (!values.ContainsKey(routeKey)) //month
{
return false;
}
Regex regex = new Regex("^(apr|jul|oct|jan)$");
string? monthValue = Convert.ToString(values[routeKey]);
if (monthValue != null && regex.IsMatch(monthValue))
{
return true; //it is a Match
}
return false;
}
}
}
- 添加服务
//添加限制类
builder.Services.AddRouting(options =>
{
options.ConstraintMap.Add("months", typeof(MonthCustomConstraint));
});
- 使用
endpoints.Map("sales-report/{year:int:min(1900)}/{month:months}", async context =>
{
int year = Convert.ToInt32(context.Request.RouteValues["year"]);
string? month = Convert.ToString(context.Request.RouteValues["month"]);
await context.Response.WriteAsync($"sales report - {year} - {month}");
});
Endpoint Selection Order
使用静态文件
- 创建文件夹
2.开启使用静态文件
r app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>{
endpoints.Map("/", async context =>{
await context.Response.WriteAsync("Hello");
});
});
app.Run();
3.浏览器直接访问静态资源,可以看到静态资源
若想修改wwwroot名字该怎么办?
- 修改名字:
- 添加配置
var builder = WebApplication.CreateBuilder(new
WebApplicationOptions()
{
WebRootPath = "myroot"
});
若想添加多个静态资源文件夹该怎么办?
-
添加文件夹
-
添加代码
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(new
WebApplicationOptions()
{
WebRootPath = "myroot"
});
var app = builder.Build();
app.UseStaticFiles(); //works with web root path (myroot)
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath,"myWebroot"))
}); //works with "mywebroot"
- 访问静态资源