给定HttpContext,从AuthorizationHandler调用查询参数的默认模型绑定器

时间:2018-12-12 21:52:28

标签: asp.net-core asp.net-core-mvc authorization asp.net-authorization

问题

在ASP.NET Core 2.2中,我正在实现AuthorizationHandler(可以在其中访问传入请求的HttpContext)。

如何从该AuthorizationHandler内为MVC使用的查询参数调用相同的模型绑定器?

理想情况下,我想编写一个扩展方法,使我可以编写以下内容:

def callAPI(entities):
  for entity in entities:
    locnum = entity[:5]
    locnumv = entity # This is redundant

    START = 1531306800  # starting time, 1 year ago
    END = START + 31536000  # final time, e.g. the current time
    TIME_STEP = 518400  # 1 day, 1 week, 1 month

    for start_time in range(START, END, TIME_STEP):
      end_time = start_time + TIME_STEP - 1 # substract 1 for preventing overlap of times

      url = "http://ex.com/api/entity/%s/timecards?start_time=%d&end_time=%d" % (entity, start_time, end_time)

      querystring = {"pretty":"1"}

      headers = {'Api-Key': ""}

      try:
          r = requests.request("GET", url, headers=headers, params=querystring)
      except:
          break

      d = r.json()

      # Do something with the data

根据名为“ membershipType”的查询参数(其中HttpContext.Request.Query.BindValue<ICollection<MembershipType>>("membershipType"); 是枚举)返回哪个新的ICollection<MembershipType>实例。

背景

假设我有一个控制器操作,其中执行查询参数的复杂模型绑定,例如,诸如此类(MembershipType是一个枚举):

MembershipType

现在,我想创建一个AuthorizationHandler,它仅对[HttpGet] [Authorize("MyPolicyThatUsesMyRequirement")] public Task<ActionResult<List<Member>>> GetMembers([FromQuery] ICollection<MembershipType> membershipTypeFilter = null) { // skipping actual implementation } 项和用户角色的某些组合成功。这意味着在我的AuthorizationHandler中,我需要访问MembershipTypeFilter参数。

让我们看一下AuthorizationHandler的以下框架:

membershipTypeFilter

class MyRequirement : AuthorizationHandler<MyRequirement>, IAuthorizationRequirement { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement) { var mvcContext = context.Resource as AuthorizationFilterContext; // TODO: need access to query parameters here return Task.CompletedTask; } } 使我可以访问查询参数,但只能以字符串数组字典的形式使用。当然,我可以解析该字符串集合,并以某种方式将其转换为枚举值的集合。但是在这种情况下,至关重要的是,这种转换必须与MVC调用我的控制器操作时完全相同。因此,我正在寻找一种调用与MVC相同的模型绑定器的方法。

1 个答案:

答案 0 :(得分:1)

对于MVC模型绑定,它由Bind实现。您将需要在自己的代码中使用它。

在我的选择中,这对于您的要求来说太重载了,更好的选择是直接从查询字符串获取值。

return [

    'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [

        ...

        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', 'homestead' == gethostname() ? 
                      'localhost' : '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'homestead'),
            'username' => env('DB_USERNAME', 'homestead'),
            'password' => env('DB_PASSWORD', 'secret'),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
        ],

如果您想尝试使用var parameters = mvcContext .ActionDescriptor .Parameters .Select(s => new { Name = s.Name, Value = mvcContext.HttpContext.Request.Query[s.Name] }); 中的MVC模型绑定,请尝试

AuthorizationHandler