【问题标题】:.NET WebApi Parameter bound optional parameter.NET WebApi Parameter 绑定可选参数
【发布时间】:2019-06-21 19:38:56
【问题描述】:

我有一个内置于 .NET WebApi 的 REST API。我创建了一个自定义参数绑定属性,用于从 HTTP 标头中提取值。在某些情况下,请求中可能存在也可能不存在标头,因此我希望能够执行以下操作将标头视为可选参数。

public IHttpActionResult Register([FromBody] RegistrationRequest request, [FromHeaderAuthorization] string authorization = null)
{

当我调用包含授权标头的端点时,这可以正常工作。 但是,在没有标头的情况下调用端点时,我收到以下错误消息:

The request is invalid.', MessageDetail='The parameters dictionary does not contain an entry for parameter 'authorization' of type 'System.String'

我一直在尝试确定是否可以以这种方式将参数视为可选参数,并发现了一些混合结果。看来,在 C# 8.0 中,我可以使用可为空的引用类型来实现这一点,但 Visual Studio 表明 8.0 当前处于预览状态,因此对我来说并不是一个真正的选择。 也就是说,我真的找不到任何其他东西来表明这种事情是否可能发生。

我的问题是,是否可以将此标头参数视为可选参数,还是我需要以不同的方式处理?

【问题讨论】:

  • 也许您可以尝试为该参数创建一个自定义 ModelBinder,并检查 nul 值
  • @carloschourio,我正在处理的用例是标题不存在,既不存在键也不存在值。在那种情况下,自定义 ModelBinder 会有用吗?在这种情况下,检查空值似乎不起作用,因为键或值根本不存在。
  • 您是否必须在控制器内部使用标头执行逻辑?我认为您可以使用过滤器从标题中获取值,并且它是否存在都没有关系。但也许您必须将逻辑放在控制器中而不是过滤器中。
  • 不一定是强制性的,不。此 REST API 是多租户服务器的前端。有两种部署场景;云和本地托管。此标头有助于识别在使用云时进行呼叫的租户。对于本地托管,托管的任何人都被视为唯一租户。这就是我正在处理的用例。所有这一切,看起来过滤器在这里可能很有用,因为我可以检查标题是否存在,如果它存在或不存在,我可以做任何我需要做的事情。我会看看朝着那个方向前进。
  • 您使用的是 ASP.NET Core 还是 .Net Framework?

标签: c# asp.net-web-api parameterbinding


【解决方案1】:

我最终放弃了 header 参数并朝着稍微不同的方向前进。

我已经创建了一个类来扩展 HttpRequestMessage 以执行诸如获取调用端点的客户端的 IP 之类的事情,我最终添加了一个方法来处理检查标头是否存在并根据需要检索必要的身份信息。

public static class HttpRequestMessageExtensions
{
    private const string HttpContext = "MS_HttpContext";
    private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";

    /* Method body excluded as irrelevant */
    public static string GetClientIpAddress(this HttpRequestMessage request) { ... }

    /** Added this method for handling the authorization header. **/
    public static Dictionary<string, string> HandleAuthorizationHeader(this HttpRequestMessage request)
    {
        Tenant tenant = new Tenant();
        IEnumerable<string> values;
        request.Headers.TryGetValues("Authorization", out values);
        string tenantConfig = ConfigurationUtility.GetConfigurationValue("tenantConfig");

        if (null != values)
        {
            // perform actions on authorization header.
        }
        else if(!string.IsNullOrEmpty(tenantConfig))
        {
            // retrieve the tenant info based on configuration.
        }
        else
        {
            throw new ArgumentException("Invalid request");
        }

        return tenant;
    }
}

【讨论】:

    猜你喜欢
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 2013-03-16
    • 1970-01-01
    相关资源
    最近更新 更多