简体   繁体   English

.NET WebApi Parameter 绑定可选参数

[英].NET WebApi Parameter bound optional parameter

I have a REST API built in .NET WebApi.我有一个内置于 .NET WebApi 的 REST API。 I have created a custom parameter binding attribute for extracting a value from HTTP headers.我创建了一个自定义参数绑定属性,用于从 HTTP 标头中提取值。 There are scenarios where the header may or may not be present on the request, so I would like to be able to do something like the following to treat the header as an optional parameter.在某些情况下,请求中可能存在也可能不存在标头,因此我希望能够执行以下操作来将标头视为可选参数。

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

This works fine when I call the endpoint with the authorization header included.当我调用包含授权标头的端点时,这很好用。 When calling the endpoint without the header however I get the following error message:但是,在没有标头的情况下调用端点时,我收到以下错误消息:

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

I have been searching to try and determine if it is possible to treat a parameter as optional in this way and have found some mixed results.我一直在寻找尝试确定是否可以以这种方式将参数视为可选参数,并发现了一些混合结果。 It appears that in C# 8.0 I could achieve this using a nullable reference type, but Visual Studio indicates that 8.0 is currently in preview and thus not really an option for me.看来,在 C# 8.0 中,我可以使用可为空的引用类型来实现这一点,但 Visual Studio 表明 8.0 当前处于预览状态,因此对我来说并不是一个真正的选择。 That said, I haven't really been able to find anything else that indicates whether this type of thing is possible or not.也就是说,我真的找不到任何其他东西来表明这种事情是否可能。

My question is, is it possible to treat this header parameter as optional or do I need to go about this differently?我的问题是,是否可以将此标头参数视为可选,还是我需要以不同的方式处理?

I ended up abandoning the header parameter and going in a slightly different direction.我最终放弃了 header 参数并朝着稍微不同的方向前进。

I had already created a class to extend HttpRequestMessage to do things like get the IP of the client calling the endpoint, I ended up adding a method to handle checking for the existence of the header and retrieving the necessary identity information as needed.我已经创建了一个类来扩展 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;
    }
}

We had the similar situation ( ASP .NET Core 6 ) where Header Parameter always considered as mandatory by the framework even though we assigned a default value ( range variable).我们遇到了类似的情况( ASP .NET Core 6 ),尽管我们分配了默认值( range变量),但框架始终认为标头参数是强制性的。

public async Task<IActionResult> GetMessages(
            [EmailAddress(ErrorMessage = "Invalid Mailbox Address")][FromRoute][Required] string mailbox,
            [FromRoute][Required] string folderId,
            [FromQuery] GetMessageBodyParameter getMessageBodyParameter,
            [FromHeader] string range = "0-9")

And we flagged the variable as nullable ( string? range ) and it is working fine now.我们将变量标记为可为空( string? range ),它现在工作正常。

public async Task<IActionResult> GetMessages(
            [EmailAddress(ErrorMessage = "Invalid Mailbox Address")][FromRoute][Required] string mailbox,
            [FromRoute][Required] string folderId,
            [FromQuery] GetMessageBodyParameter getMessageBodyParameter,
            [FromHeader] string? range = "0-9")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM