7

I am trying to pass multiple parameters to a httpget web api function. The key problem I am having is that empty query string parameters are being converted to null.

I can solve this by creating a class like something below:

public class CuttingParams
{
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string batch_number { get; set; }
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string filter { get; set; }
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string initiation_month { get; set; }
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string initiation_year { get; set; }
}

But I absolutely friggin hate the idea of having to create a class for a once off use.

Ive done a lot of research and am really struggling to find a way to change the default behaviour other than above. I really just want to do this:

    [HttpGet]
    public object Search(string batch_number, string filter, string initiation_month, string initiation_year)
    {
    }

Am I missing an easy to way to change this default behaviour or what should I be looking at to impelement my own query string parser that I can apply globally?

Thanks

Update

There seems to be some confusion about my post, sorry if I wasn't clear. I will try to clarify.

I want to pass in just simple primitive types to my HttpGet method as shown in the second code snippet. The problem I have is that empty string parameters will get converted to null.

ie. this url: http://localhost/api/cutting/search?batch_number=&filter=&intiation_month=Jan&initiation_year=2016

will produce the following values in the api:

batch_number = null
filter = null
initiation_month = Jan
initiation_year = 2016

If I change the search function to use the class in the first code snippet, it will work as I want, but Im really trying to avoid using classes for api parameters in the long term.

5
  • I'm trying to understand what is you expected result. Is it that you want, in your example, that is the parameter is not bound that they are set to an empty string and not null? Commented Mar 12, 2016 at 13:37
  • did you try DefaultValueAttribute? Something like: [DefaultValue("")] public string initiation_year { get; set; } Commented Mar 12, 2016 at 13:50
  • 1
    @Nkosi What i am after is that the parameter is set to exacty what i pass in, ie. if i pass in an empty string, i want it to be an empty string, at the moment, if i pass in an empty string, the parameter value will be null Commented Mar 12, 2016 at 21:58
  • @Khanh_TO The class with its displayformat attributes is working, i dont want to create a class, i just want to use individual parameters as shown in the second code snippet Commented Mar 12, 2016 at 22:00
  • I got my answer (=now using: ConvertEmptyStringToNull = false) from your question. Nice! Commented Jul 7, 2016 at 7:49

2 Answers 2

1

Ok, I got this working the way I want. I had to adapt some similar code I found for an mvc web api, but made it a lot simpler. Create your custom model binder as below and add it to the globalconfiguration. Hope this helps someone else.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        GlobalConfiguration.Configuration.BindParameter(typeof(string), new EmptyStringModelBinder());

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}"
        );
    }
}

public class EmptyStringModelBinder : System.Web.Http.ModelBinding.IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
    {
        string val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;
        bindingContext.Model = val;

        return true;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

I believe that is by design. If the ModelBinder cannot map the parameter, it reverts to the default type of the parameter.

The same would happen if it was a simple value type like int where it would set that value to 0

Have a look at the following article to see if it can help you

Parameter Binding in ASP.NET Web API

1 Comment

It is by design. I don't want default behaviour. I know you can create custom formatters etc to override web api behaviour, but I dont know what to look at to try and override this default behaviour of changing empty string parameters to null when just using primitive types as parameters

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.