更新时间:2022-02-23 01:05:43
这似乎是可以通过定义一个定制的路由做到这一点。在MVC4(最新稳定释放4.0.30506.0),它是不可能通过实施 IHttpRoute
根据规范,但通过定义一个定制的MVC级做路线
并直接将它添加到 RouteTable
。有关详情请参见 1 ,的 2 。下面的 RegexRoute
的实施是基于执行这里与答案
It seems that it is possible to do this by defining a custom route. In MVC4 (last stable released 4.0.30506.0), it is not possible to do by implementing IHttpRoute
as per specification but by defining a custom MVC-level Route
and adding it directly to the RouteTable
. For details see 1, 2. The RegexRoute
implementation below is based on the implementation here with mods from the answer here.
定义 RegexRoute
:
public class RegexRoute : Route
{
private readonly Regex urlRegex;
public RegexRoute(string urlPattern, string routeTemplate, object defaults, object constraints = null)
: base(routeTemplate, new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(), HttpControllerRouteHandler.Instance)
{
urlRegex = new Regex(urlPattern, RegexOptions.Compiled);
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
string requestUrl = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
Match match = urlRegex.Match(requestUrl);
RouteData data = null;
if (match.Success)
{
data = new RouteData(this, RouteHandler);
// add defaults first
if (null != Defaults)
{
foreach (var def in Defaults)
{
data.Values[def.Key] = def.Value;
}
}
// iterate matching groups
for (int i = 1; i < match.Groups.Count; i++)
{
Group group = match.Groups[i];
if (group.Success)
{
string key = urlRegex.GroupNameFromNumber(i);
if (!String.IsNullOrEmpty(key) && !Char.IsNumber(key, 0)) // only consider named groups
{
data.Values[key] = group.Value;
}
}
}
}
return data;
}
}
将此 DelegatingHandler
来避免 NullReference
由于一些其它的错误:
Add this DelegatingHandler
to avoid a NullReference
due to some other bug:
public class RouteByPassingHandler : DelegatingHandler
{
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
HttpMessageInvoker invoker = new HttpMessageInvoker(new HttpControllerDispatcher(request.GetConfiguration()));
return invoker.SendAsync(request, cancellationToken);
}
}
直接添加处理和路由到 RouteTable
:
RouteTable.Routes.Add(new RegexRoute(@"^api/home/index/(?<id>\d+)$", "test", new { controller = "Home", action = "Index" }));
config.MessageHandlers.Add(new RouteByPassingHandler());
乙醚瞧!
修改:这个解决方案有问题,当空气污染指数是自托管(而不是使用一个虚拟主机提供商),需要进一步的工作,使之既工作。如果这是有趣的人,请留下评论,我会后我的解决方案。
EDIT: This solution has problems when the API is self-hosted (instead of using a WebHost) and requires further work to make it work with both. If this is interesting to anyone, please leave a comment and I'll post my solution.