路由特定 ASP.NET MVC Web API 消息处理程序未调用控制器操作
Route-specific ASP.NET MVC Web API message handler not invoking controller action
我有一个 ASP.NET MVC Web API 控制器:
[HttpPost]
public async Task<HttpResponseMessage> Post(HttpRequestMessage req, CancellationToken cancellationToken) {...}
以及我创建的自定义消息处理程序:
public class MyMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// ...
var response = await base.SendAsync(request, cancellationToken);
// ...
return response;
}
}
并且在 WebConfigApi.cs
中,我将特定于控制器操作方法的消息处理程序路由连接起来:
configuration.Routes.MapHttpRoute(
name: "UpdateStuffAPI",
routeTemplate: "api/updatestuff/post/{stuffid}",
defaults: new { feedid = RouteParameter.Optional },
constraints: null,
handler: new MyMessageHandler()
);
当我POST到控制器动作方法时,例如:
http://hostname/api/updatestuff/post?stuffid=12345
消息处理程序按预期拦截请求。但是在单步执行中:
var response = await base.SendAsync(request, cancellationToken);
永远不会命中控制器操作方法。
作为测试,我删除了特定于路由的连接并将消息处理程序设置为全局:
configuration.MessageHandlers.Add(new MyMessageHandler());
和 SendAsync
正确调用我的控制器的操作方法。
所以我的想法是路由定义有问题。但是,消息处理程序 是 通过特定于路由的连接调用的, 和 ,Route Debugger 表明当我 POST到我的控制器(http://hostname/api/updatestuff/post?stuffid=12345
),那条路线正在被使用。
当我以特定于路由的方式连接消息处理程序时,为什么我的操作方法没有被调用?
您是否尝试过使用以下方式启用属性路由:
configuration.Routes.MapMvcAttributeRoutes();
路由还取决于映射属性路由和普通 http 路由的顺序。
我遗漏了将消息处理程序绑定回 route/controller 它接下来应该调用的代码。
必须特别告知特定于路由的消息处理程序有关 Web Api 应用程序的 HttpConfiguration
。我在 WebConfigApi.cs
中拥有的是:
configuration.Routes.MapHttpRoute(
name: "UpdateStuffAPI",
routeTemplate: "api/updatestuff/post/{stuffid}",
defaults: new { feedid = RouteParameter.Optional },
constraints: null,
handler: new MyMessageHandler()
);
我需要的是:
configuration.Routes.MapHttpRoute(
name: "UpdateStuffAPI",
routeTemplate: "api/updatestuff/post/{stuffid}",
defaults: new { feedid = RouteParameter.Optional },
constraints: null,
handler: new MyMessageHandler(configuration)
);
换句话说,配置对象需要在构建时传递给消息处理程序。所以消息处理程序需要一个构造函数:
public MyMessageHandler(HttpConfiguration httpConfiguration)
{
InnerHandler = new HttpControllerDispatcher(httpConfiguration);
}
我天真地假设在路由映射中设置 handler: new MyMessageHandler()
足以将消息处理程序绑定回路由映射到的控制器。
虽然这个问题已解决,但我承认我还不明白为什么需要这样做(为什么我的假设不正确)所以我将继续阅读。
我有一个 ASP.NET MVC Web API 控制器:
[HttpPost]
public async Task<HttpResponseMessage> Post(HttpRequestMessage req, CancellationToken cancellationToken) {...}
以及我创建的自定义消息处理程序:
public class MyMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// ...
var response = await base.SendAsync(request, cancellationToken);
// ...
return response;
}
}
并且在 WebConfigApi.cs
中,我将特定于控制器操作方法的消息处理程序路由连接起来:
configuration.Routes.MapHttpRoute(
name: "UpdateStuffAPI",
routeTemplate: "api/updatestuff/post/{stuffid}",
defaults: new { feedid = RouteParameter.Optional },
constraints: null,
handler: new MyMessageHandler()
);
当我POST到控制器动作方法时,例如:
http://hostname/api/updatestuff/post?stuffid=12345
消息处理程序按预期拦截请求。但是在单步执行中:
var response = await base.SendAsync(request, cancellationToken);
永远不会命中控制器操作方法。
作为测试,我删除了特定于路由的连接并将消息处理程序设置为全局:
configuration.MessageHandlers.Add(new MyMessageHandler());
和 SendAsync
正确调用我的控制器的操作方法。
所以我的想法是路由定义有问题。但是,消息处理程序 是 通过特定于路由的连接调用的, 和 ,Route Debugger 表明当我 POST到我的控制器(http://hostname/api/updatestuff/post?stuffid=12345
),那条路线正在被使用。
当我以特定于路由的方式连接消息处理程序时,为什么我的操作方法没有被调用?
您是否尝试过使用以下方式启用属性路由:
configuration.Routes.MapMvcAttributeRoutes();
路由还取决于映射属性路由和普通 http 路由的顺序。
我遗漏了将消息处理程序绑定回 route/controller 它接下来应该调用的代码。
必须特别告知特定于路由的消息处理程序有关 Web Api 应用程序的 HttpConfiguration
。我在 WebConfigApi.cs
中拥有的是:
configuration.Routes.MapHttpRoute(
name: "UpdateStuffAPI",
routeTemplate: "api/updatestuff/post/{stuffid}",
defaults: new { feedid = RouteParameter.Optional },
constraints: null,
handler: new MyMessageHandler()
);
我需要的是:
configuration.Routes.MapHttpRoute(
name: "UpdateStuffAPI",
routeTemplate: "api/updatestuff/post/{stuffid}",
defaults: new { feedid = RouteParameter.Optional },
constraints: null,
handler: new MyMessageHandler(configuration)
);
换句话说,配置对象需要在构建时传递给消息处理程序。所以消息处理程序需要一个构造函数:
public MyMessageHandler(HttpConfiguration httpConfiguration)
{
InnerHandler = new HttpControllerDispatcher(httpConfiguration);
}
我天真地假设在路由映射中设置 handler: new MyMessageHandler()
足以将消息处理程序绑定回路由映射到的控制器。
虽然这个问题已解决,但我承认我还不明白为什么需要这样做(为什么我的假设不正确)所以我将继续阅读。