如何在Web API路由中捕获并接受特定的动作名称?

时间:2019-05-17 10:43:52

标签: asp.net-mvc asp.net-web-api

我们正在设计一个网络api,我们希望捕获对api的所有请求并获取操作名称,并检查其是否在数据库中可用,如果可以, 一个方法就可以了。
实际上方法的名称应该是客户银行帐户! 我知道这似乎很奇怪,但是我们被要求以这种方式来做,比如说我们在请求地址下方

www.webSiteAddress.com/api/paya/123456789?amount=25&span=4587

123456789是我们的客户银行帐户,应用作操作名称!  但首先我们应该从数据库中检查它 我想出了以下解决方案,但是没有用。

public class IBanRoutingConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        object IBan;
        values.TryGetValue("action", out IBan);
        if (IBan!=null && db.Accounts.Any(x=>x.AccountNo==IBan))
        {                
            return true;
        }
        return false;
    }
}

并且我将其用作Web api路由的约束。

public static void Register(HttpConfiguration config)
{
  config.MapHttpAttributeRoutes();

  config.Routes.MapHttpRoute(
  name: "PayaApi",
  routeTemplate: "api/{controller}/{action}",
  defaults: new { id = RouteParameter.Optional },
  constraints: new { action = new IBanRoutingConstraint() });
}

但我最终收到了此消息...

No action was found on the controller 'Paya' that matches the name '123456789'

1 个答案:

答案 0 :(得分:0)

最后我发现了我的自我... 对于这种情况,我应该经历两个步骤 首先对Web api路由中的操作施加如下约束

public class IBanRoutingConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        object IBan;
        values.TryGetValue("action", out IBan);
        if (IBan!=null && db.Accounts.Any(x=>x.AccountNo==IBan))
        {                
            return true;
        }
        return false;
    }
}

然后我需要通知api动作选择器在动作选择过程中如何处理选择动作方法

public class PayaActionSelector : ApiControllerActionSelector
{
    public override HttpActionDescriptor SelectAction(HttpControllerContext context)
    {
        var actionMethod = context.ControllerDescriptor.ControllerType
         .GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(x=>x.Name=="Index");
        return new ReflectedHttpActionDescriptor(context.ControllerDescriptor, actionMethod);
    }
}

和api路由配置将是这样

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
      config.MapHttpAttributeRoutes();

      config.Routes.MapHttpRoute(
      name: "PayaApi",
      routeTemplate: "api/{controller}/{action}/{id}",
      defaults: new { id = RouteParameter.Optional },
      constraints: new { action = new IBanRoutingConstraint() });
      config.Services.Replace(typeof(IHttpActionSelector),
                               new PayaActionSelector());
    }
}