防止ASP.NET的WebAPI 2从处理空字符串查询参数为空

时间:2019-02-01 17:46:42

标签: c# asp.net string null asp.net-web-api2

我有一个使用ASP.NET WebAPI 2构建的RESTful Web服务。

我在控制器中有此方法:

[Route("{DocNum:int}")]
public object Patch(int DocNum, string str = null)
{
    if(str == null)
    {
        //do something when parameter has NOT been passed...
    }
    else
    {
        //do something when parameter has been passed...
    }
}

如果我不通过str,则该方法中的值为空。

如果我通过str=abc,则该方法为“ abc”。

如果我传递了str=(空字符串),则该方法中的值为空。

这就是ASP.NET WebAPI 2将空字符串查询参数视为null!

似乎是设计使然,但是有一种方法可以将空字符串作为空字符串处理?

2 个答案:

答案 0 :(得分:1)

HTML中不存在null。输入具有某个值或空值。甚至没有办法仅通过查询参数来判断该值是字符串还是数字。

HTML表单的默认行为是在提交时包括所有字段。因此,即使输入没有值,它仍将作为查询的一部分包括在内。 $ awk -f a.awk file "1547485175",Local Mgmt Services "1548683908",Local Broadcast Noise "1547555119",pfb_Bad_IP (outbound) "1547478025",Anti-Lockout "1548774638",Policy Route www.example.com/xxx?str=都是有效的语法,表示没有为www.example.com/xxx字段输入任何值。

但是您可以包含一个隐藏字段

str

在表单中,并使用JavaScript根据您用来确定其为空还是空的任何逻辑来设置值。

答案 1 :(得分:0)

我找到了一个很棒的解决方案,它是从https://stackoverflow.com/a/35966463/505893复制而来的,并且得到了改进。这是Web应用程序全局配置中的自定义。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //treat query string parameters of type string, that have an empty string value,
        //(e.g. http://my/great/url?myparam=) as... empty strings!
        //and not as null, which is the default behaviour
        //see https://stackoverflow.com/q/54484640/505893
        GlobalConfiguration.Configuration.BindParameter(typeof(string), new EmptyStringModelBinder());

        //...
    }
}

/// <summary>
/// Model binder that treats query string parameters that have an empty string value
/// (e.g. http://my/great/url?myparam=) as... empty strings!
/// And not as null, which is the default behaviour.
/// </summary>
public class EmptyStringModelBinder : System.Web.Http.ModelBinding.IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
    {
        var vpr = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (vpr != null)
        {
            //parameter has been passed
            //preserve its value!
            //(if empty string, leave it as it is, instead of setting null)
            bindingContext.Model = vpr.AttemptedValue;
        }

        return true;
    }
}