Search code examples
c#asp.net-web-apiparameters

.NET WebAPI parameter bound optional parameter


I have a REST API built in .NET Framework WebAPI. I have created a custom parameter binding attribute for extracting a value from HTTP headers. 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.

That said, I haven't really been able to find anything else that indicates whether this type of thing is possible or not.

Is it possible to treat this header parameter as optional or do I need to go about this differently?


Solution

  • I ended up abandoning the header parameter and going in a slightly different direction.

    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.

    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;
        }
    }