带有 MapHttpAttributeRoutes 的 HttpMessageHandler 不工作
HttpMessageHandler with MapHttpAttributeRoutes not working
我正在 this tutorial 尝试获取此图像中 MessageHandler3 的行为:
这是我的一个控制器的一部分:
public class UserController : ApiController
{
[Route("api/users")]
[ResponseType(typeof(User))]
public IHttpActionResult PostUser([FromBody]User newUser)
{
try
{
userService.InsertUser(newUser);
return Ok(newUser);
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
}
这是处理程序的虚拟版本:
public class UserTokenHandler : DelegatingHandler
{
public UserTokenHandler()
{
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (true)//actual validation method
{
var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return tsc.Task;
}
return base.SendAsync(request, cancellationToken);
}
}
下面是我对 WebApiConfig 所做的更改 class:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//config.MapHttpAttributeRoutes();
var handlers = new DelegatingHandler[] { new UserTokenHandler() };
var routeHandlers = HttpClientFactory.CreatePipeline(new HttpControllerDispatcher(config), handlers);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: routeHandlers
);
config.MapHttpAttributeRoutes();
}
}
我的问题是注释行。如果我不包含它或将它放在末尾(就像现在这样),处理程序会执行,但在尝试使用我的 api:
时出现此错误
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:12986/api/users'.",
"MessageDetail": "No type was found that matches the controller named 'users'."
}
但是,如果我取消注释(并删除底部的那个),我会直接进入控制器,而无需通过处理程序。
我希望它通过处理程序然后找到方法,我该如何解决?
如果没记错的话,打电话给
至关重要
config.MapHttpAttributeRoutes();
在你打电话之前
config.Routes.MapHttpRoute
如果需要,您实际上可以在映射之前添加处理程序。
config.MessageHandlers.Add(new UserTokenHandler());
config.MapHttpAttributeRoutes();
//...other code
我已经完成了这个并实现了节流处理程序并且工作起来非常棒,但这将适用于所有传入的请求。
如果您希望它仅适用于用户控制器,那么您需要放弃属性路由并为用户控制器使用基于约定的路由。
但是,如果您混合使用了基于约定的路由和属性路由,那么就不会很好地混合,因为正如您链接到的文章中所述。这更适合基于约定的路由。
我正在 this tutorial 尝试获取此图像中 MessageHandler3 的行为:
这是我的一个控制器的一部分:
public class UserController : ApiController
{
[Route("api/users")]
[ResponseType(typeof(User))]
public IHttpActionResult PostUser([FromBody]User newUser)
{
try
{
userService.InsertUser(newUser);
return Ok(newUser);
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
}
这是处理程序的虚拟版本:
public class UserTokenHandler : DelegatingHandler
{
public UserTokenHandler()
{
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (true)//actual validation method
{
var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return tsc.Task;
}
return base.SendAsync(request, cancellationToken);
}
}
下面是我对 WebApiConfig 所做的更改 class:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//config.MapHttpAttributeRoutes();
var handlers = new DelegatingHandler[] { new UserTokenHandler() };
var routeHandlers = HttpClientFactory.CreatePipeline(new HttpControllerDispatcher(config), handlers);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: routeHandlers
);
config.MapHttpAttributeRoutes();
}
}
我的问题是注释行。如果我不包含它或将它放在末尾(就像现在这样),处理程序会执行,但在尝试使用我的 api:
时出现此错误{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:12986/api/users'.",
"MessageDetail": "No type was found that matches the controller named 'users'."
}
但是,如果我取消注释(并删除底部的那个),我会直接进入控制器,而无需通过处理程序。
我希望它通过处理程序然后找到方法,我该如何解决?
如果没记错的话,打电话给
至关重要config.MapHttpAttributeRoutes();
在你打电话之前
config.Routes.MapHttpRoute
如果需要,您实际上可以在映射之前添加处理程序。
config.MessageHandlers.Add(new UserTokenHandler());
config.MapHttpAttributeRoutes();
//...other code
我已经完成了这个并实现了节流处理程序并且工作起来非常棒,但这将适用于所有传入的请求。
如果您希望它仅适用于用户控制器,那么您需要放弃属性路由并为用户控制器使用基于约定的路由。
但是,如果您混合使用了基于约定的路由和属性路由,那么就不会很好地混合,因为正如您链接到的文章中所述。这更适合基于约定的路由。