1 回答
TA贡献1784条经验 获得超8个赞
恐怕没有内置的路由可以满足您的需求。但是,编写自定义中间件很容易。
简短的回答:
写一个谓词,它将设置
Context.Items["Ids"]
和Context.Items["WantChildren"]
将谓词传递给
MapWhen()
方法。编写一个中间件来处理逻辑以显示内容或根据
Context.Items["Ids"]
和获取它的孩子Context.Items["WantChildren"]
。
快速而肮脏的演示
这是一个快速而肮脏的演示:
app.MapWhen(
context =>{
var path=context.Request.Path.ToString().ToLower();
if (path.EndsWith("/")) {
path = path.Substring(0, path.Length-1);
}
if (!path.StartsWith("/api/content")) {
return false;
}
var ids = new List<int>();
var wantChildren = false;
var match= Regex.Match(path,"/(?<id>\\d+)(?<children>/children)?");
while (match.Success) {
var id = Convert.ToInt32(match.Groups["id"].Value); // todo: if throws an exception , ...
wantChildren= !String.IsNullOrEmpty(match.Groups["children"].Value);
ids.Add(id);
match = match.NextMatch();
}
context.Items["Ids"] = ids;
context.Items["WantChildren"] = wantChildren;
return true;
},
appBuilder => {
appBuilder.Run(async context =>{
var ids = (List<int>)(context.Items["Ids"]);
var wantChildren = (bool)(context.Items["WantChildren"]);
// just a demo
// the code below should be replaced with those that you do with id list and whether you should display children
foreach (var id in ids) {
await context.Response.WriteAsync(id.ToString());
await context.Response.WriteAsync(",");
}
await context.Response.WriteAsync(wantChildren.ToString());
});
}
);
这是一个有效的屏幕截图
进一步重构
为了更好地维护,您可以提取Ids和WantChildren到单个 Class ,例如ContentChildrenContext:
public class ContentChildrenContext{
public List<int> Ids {get;set;}
public bool WantChildren{get;set;}
}
您还可以围绕中间件本身进行抽象,例如,创建一个返回 RequestDelegate 的工厂方法,该方法可以轻松用于app.Run():
Func<Func<ContentChildrenContext,Task>,RequestDelegate> CreateContentChildrenMiddleware(Func<ContentChildrenContext,Task> action){
return async content =>{
var ccc= (ContentChildrenContext)(context.Items["ContentChildrenContext"]);
await action(ccc);
};
}
- 1 回答
- 0 关注
- 162 浏览
添加回答
举报