C# Web API参数绑定返回实例,即使没有请求参数

C# Web API参数绑定返回实例,即使没有请求参数,c#,asp.net,asp.net-web-api,C#,Asp.net,Asp.net Web Api,有了ASP.NET的WebApi,我如何确保一个复杂的动作参数总是被实例化?即使没有请求参数(在QueryString或POST正文中) 例如,给定此虚拟动作定义: public IHttpActionResult GetBlahBlah(GetBlahBlahInput input) { .. } 我希望input始终是GetBlahBlahInput的实例化实例。默认行为是,如果请求参数存在于请求中的任何位置,则输入不为null(即使没有任何请求参数可绑定到GetBlahBlahInput

有了ASP.NET的WebApi,我如何确保一个复杂的动作参数总是被实例化?即使没有请求参数(在QueryString或POST正文中)

例如,给定此虚拟动作定义:

public IHttpActionResult GetBlahBlah(GetBlahBlahInput input) { .. }
我希望
input
始终是
GetBlahBlahInput
的实例化实例。默认行为是,如果请求参数存在于请求中的任何位置,则
输入
不为null(即使没有任何请求参数可绑定到
GetBlahBlahInput
),但是,如果没有发送参数,则
GetBlahBlahInput
null
。我不想要
null
,我想要一个使用无参数构造函数创建的实例

基本上,我正在尝试实现这一点:

在WebApi中(所以没有
DefaultModelBinder
Inheritation),我希望它是泛型的,这样它就可以处理任何输入类型

我在WebApi中使用默认的JSONMediaFormat支持


有什么想法吗?我很确定这是可以做到的,我可能在某个地方错过了一个简单的配置步骤。

我仍然想知道我所问的是否可以做到。但就目前而言,以下是我在ActionFilterAttribute中实现的解决方法(
inputKey
是参数的名称;在原始问题中是
input
):


难道你不能直接做一个if(input==null)input=newgetblahblahinput()吗;在方法的第一行?非常简单,但可能我遗漏了一些我不需要的东西——我正在编写一个ActionFilterAttribute,它将为输入模型上的属性赋值。所以这是在动作实际触发之前(我覆盖了ActionExecuting()。如果我能确定ActionFilterAttribute中的输入类型,我可以在那里处理它,但感觉不对。感觉正确的是ModelBinder总是返回一个实例化的对象。我知道你现在想做什么了。据我所知,WebAPI对基本类型使用ModelBinder,对复杂类型使用格式化程序。我担心,你最终会增加很多复杂性,试图强迫人们做出某种并非本意的行为。我宁愿使用标准的方法,并接受输入可能是空的,如果它没有提供。很抱歉,我帮不上忙。您是否使用属性路由,因为此和属性路由存在已知问题?我使用的是属性路由,是的。您是否找到其他方法来执行此操作?不,我从未找到过。但是我已经有将近一年半没有使用WebApi编程了,所以我已经失去了对最新和最伟大的东西的联系
// look for the "input" parameter and try to instantiate it and see if it implements the interface I'm interested in
var parameterDescriptor = actionContext.ActionDescriptor.GetParameters().FirstOrDefault(p => string.Compare(p.ParameterName, inputKey, StringComparison.InvariantCultureIgnoreCase) == 0);
if (parameterDescriptor == null 
    || (inputArgument = Activator.CreateInstance(parameterDescriptor.ParameterType) as IHasBlahBlahId) == null)
{
    // if missing "input" parameter descriptor or it isn't an IHasBlahBlahId, then return unauthorized
    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
    return;
}

// otherwise, take that newly instantiated object and throw it into the ActionArguments!
if (actionContext.ActionArguments.ContainsKey(inputKey))
    actionContext.ActionArguments[inputKey] = inputArgument;
else
    actionContext.ActionArguments.Add(inputKey, inputArgument);