asp.net-mvc - 在 .net Core 中按名称定义 MVC 路由
问题描述
我定义了 2 条路线:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("api", "{controller=Home}/api/v1/{action=Index}/{id?}");
});
在控制器中,如果我没有在控制器中指定路由,它将使用其中任何一个。两个网址都有效:
https://myapp/mymodel/api/v1/id/123
我希望它仅适用于第一个 url,但如果将例如 [Route("api")] 添加到控制器,则上述路由都不起作用。
[Route("api")] //with this line it returns 404
public mymodel ID(int? id)
{
//some code
}
解决方案
来自官方文档:
路由名称可用于根据特定路由生成 URL。路由名称对路由的 URL 匹配行为没有影响,仅用于 URL 生成。路由名称在应用程序范围内必须是唯一的。
这是自定义一个 actionfilter 属性的解决方法,该属性检查 url 是否与 api 的路由模板匹配,您可以参考:
ApiRouteTemplateAttribute
public class ApiRouteTemplateAttribute:ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var routeTemplate = "{controller=Home}/api/v1/{action=Index}/{id?}";
var template = TemplateParser.Parse(routeTemplate);
var matcher = new TemplateMatcher(template, GetDefaults(template));
var routeValues = new RouteValueDictionary();
string LocalPath = context.HttpContext.Request.Path;
var result = matcher.TryMatch(LocalPath, routeValues);
//if the match is false ,return a exception information.
if (!result)
{
context.Result = new BadRequestObjectResult(new Exception("The url is incorrect!"));
}
}
private RouteValueDictionary GetDefaults(RouteTemplate parsedTemplate)
{
var result = new RouteValueDictionary();
foreach (var parameter in parsedTemplate.Parameters)
{
if (parameter.DefaultValue != null)
{
result.Add(parameter.Name, parameter.DefaultValue);
}
}
return result;
}
}
控制器
[ApiRouteTemplate]
public Exam ID(int? id)
{
return _context.Exams.Find(id);
}
结果
推荐阅读
- javascript - 覆盖现有的 JavaScript Array.prototype 方法会导致无限递归?
- python - 定义一个函数以从 3 个数字中选择 2 个较大的数字,然后将 2 个数字的平方相加
- ember.js - Ember 如何决定何时在后台重新渲染组件?
- python - 在发送标准输入输入之前等待来自子进程的提示
- regex - 正则表达式:使用竖线时捕获组的索引是多少
- javascript - 如何在 React 中正确加载 JSON 文件?
- python - 如何使用 nbconvert to pdf 在 Jupyter 中隐藏代码单元?
- vba - MS Access VBA - 具有相同名称的私有子
- c# - 2018 Unity Void Update()不更新第二行?
- vue.js - Vue 上的 Window.resize 无法编译