Ben
Ben

Reputation: 2725

Web API whitespace parameter value being converted to null

I have a simple web API service. There are about 10 different GET actions and these return a JSON output of various database records based on the input parameters.

For one particular endpoint a single space, ' ' should be a valid argument but this is being converted to null. Is there a way around this?

For example the URL is: http://localhost:1234/DataAccess/RetrieveProductData?parameterOne=null&parameterTwo=574&problemParameter=%20&parameterThree=AB12

Within the controller action I can see the following:

int? parameterOne => null
string parameterTwo => "574"
string problemParameter => null
string parameterThree => "AB12"

Is there any way to actually get:

string problemParameter => " "

Or is this not possible?

Upvotes: 2

Views: 845

Answers (2)

Ben
Ben

Reputation: 2725

I resolved this issue by adding a ParameterBindingRule with sufficient criteria to match on the exact parameter I had an issue with:

Register code:

config.ParameterBindingRules.Add(p =>
            {
                // Override rule only for string and get methods, Otherwise let Web API do what it is doing
                // By default if the argument is only whitespace, it will be set to null. This fixes that
                // commissionOption column default value is a single space ' '.
                // Therefore a valid input parameter here is a ' '. By default this is converted to null. This overrides default behaviour.
                if (p.ParameterType == typeof(string) && p.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Get) && p.ParameterName == "commissionOption")
                {
                    return new StringParameterBinding(p);
                }

                return null;
            });

StringParameterBinding.cs:

public StringParameterBinding(HttpParameterDescriptor parameter)
    : base(parameter)
{
}

public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
{
    var value = actionContext.Request.GetQueryNameValuePairs().Where(f => f.Key == this.Descriptor.ParameterName).Select(s => s.Value).FirstOrDefault();

    // By default if the argument is only whitespace, it will be set to null. This fixes that
    actionContext.ActionArguments[this.Descriptor.ParameterName] = value;

    var tsc = new TaskCompletionSource<object>();
    tsc.SetResult(null);
    return tsc.Task;
}

Upvotes: 1

Nima Owji
Nima Owji

Reputation: 665

You should do it in the client app. Do you want to deserialize it on Android?

Upvotes: 0

Related Questions