gpt4 book ai didi

c# - 查看将从路由执行哪个 Controller 和操作?

转载 作者:太空狗 更新时间:2023-10-29 23:20:18 25 4
gpt4 key购买 nike

在 ASP .NET Core 中,如何给定路由(例如 /api/users/28)查看将使用哪个 Controller 以及将使用哪个操作?例如,在这种情况下,它将是 UsersController 及其 Get(int id) 操作。

如果有一种方法可以访问某种可以告诉我这一点的路由器,我会很高兴,这样我就不必自己复制内部路由系统了。我只是无法使用有关 ASP .NET Core 路由的官方文档找到它。

编辑 1 我的问题不是重复的。我不是在寻找确定路线是否存在的选项 - 我想知道确切的操作和 Controller 将处理它。

编辑 2 这是我当前的代码以及我尝试过的代码:

var httpContext = new DefaultHttpContext();
httpContext.Request.Path = "/api/users/28";
httpContext.Request.Method = "GET";

var context = new RouteContext(httpContext);

//throws an exception: AmbiguousActionException: Multiple actions matched.
var bestCandidate = _actionSelector.SelectBestCandidate(context,
_actionDescriptorCollectionProvider.ActionDescriptors.Items);

最佳答案

看起来 IActionSelector 只匹配 HTTP 方法等,完全忽略路由模板。

感谢Sets回答和https://blog.markvincze.com/matching-route-templates-manually-in-asp-net-core/ ,我想出了以下解决方案:

public ManualActionSelector(IActionSelector actionSelector, IActionDescriptorCollectionProvider actionDescriptorCollectionProvider)
{
_actionSelector = actionSelector;
_actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
}

public ActionDescriptor GetMatchingAction(string path, string httpMethod)
{
var actionDescriptors = _actionDescriptorCollectionProvider.ActionDescriptors.Items;

// match by route template
var matchingDescriptors = new List<ActionDescriptor>();
foreach (var actionDescriptor in actionDescriptors)
{
var matchesRouteTemplate = MatchesTemplate(actionDescriptor.AttributeRouteInfo.Template, path);
if (matchesRouteTemplate)
{
matchingDescriptors.Add(actionDescriptor);
}
}

// match action by using the IActionSelector
var httpContext = new DefaultHttpContext();
httpContext.Request.Path = path;
httpContext.Request.Method = httpMethod;
var routeContext = new RouteContext(httpContext);
return _actionSelector.SelectBestCandidate(routeContext, matchingDescriptors.AsReadOnly());
}


public bool MatchesTemplate(string routeTemplate, string requestPath)
{
var template = TemplateParser.Parse(routeTemplate);

var matcher = new TemplateMatcher(template, GetDefaults(template));
var values = new RouteValueDictionary();
return matcher.TryMatch(requestPath, values);
}

// This method extracts the default argument values from the template. From https://blog.markvincze.com/matching-route-templates-manually-in-asp-net-core/
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;
}

它首先尝试通过模板匹配所有路由。它调用 IActionSelector,剩下的由它来完成。你可以像这样使用它:

var action = GetMatchingAction("/api/users/28", "GET"); // will return null if no matching route found

关于c# - 查看将从路由执行哪个 Controller 和操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46038337/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com