【问题标题】:Web API Parameter Binding return instance even without request parameters即使没有请求参数,Web API 参数绑定也会返回实例
【发布时间】:2014-03-31 15:02:15
【问题描述】:

使用 ASP.NET 的 WebApi,如何确保始终实例化复杂的 Action 参数?即使没有请求参数(在 QueryString 或 POST 正文中)。

例如,给定这个虚拟动作定义:

public IHttpActionResult GetBlahBlah(GetBlahBlahInput input) { .. }

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

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

http://dotnet.dzone.com/articles/interesting-json-model-binding

在 WebApi 领域(所以没有 DefaultModelBinder 继承),我希望它是通用的,因此它可以处理任何输入类型。

我在 WebApi 中使用默认的 JsonMediaFormatter 支持。

有什么想法吗?我很确定它可以完成,我可能在某处缺少一个简单的配置步骤。

【问题讨论】:

  • 你不能直接做一个 if (input == null) input = new GetBlahBlahInput();在方法的第一行?很简单,但也许我错过了什么
  • 不是我需要的——我正在编写一个 ActionFilterAttribute,它将为输入模型上的属性分配值。所以这是在 Action 实际触发之前(我正在覆盖 ActionExecuting())。如果我可以确定 ActionFilterAttribute 中的输入类型,我可以在那里处理它,但感觉不对。感觉正确的是 ModelBinder 总是返回一个实例化的对象。
  • 我知道你现在想做什么。据我了解,WebAPI 将 ModelBinder 用于原始类型,将 Formatter 用于复杂类型。恐怕你最终会增加很多复杂性,试图强制执行某种非预期的行为。我宁愿使用标准方式并接受如果未提供输入可能为空。抱歉,我帮不上忙。
  • 您是否使用属性路由,因为此和属性路由存在已知问题?
  • 我正在使用属性路由,是的。

标签: c# asp.net asp.net-web-api


【解决方案1】:

我仍然想知道我问的是否可以完成。但目前,这是我在 ActionFilterAttribute 中实现的解决方法(inputKey 是参数的名称;在原始问题中是input):

// 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);

【讨论】:

  • 您找到其他方法了吗?
  • 不,我从来没有。但是我已经快一年半没有使用 WebApi 编码了,所以我对最新最好的东西失去了联系。
  • 还不错,但是一年半之后,最新最好的还是坏了:P
猜你喜欢
  • 1970-01-01
  • 2015-05-12
  • 1970-01-01
  • 2021-12-27
  • 2021-02-08
  • 2015-05-26
  • 2019-06-05
  • 2013-12-25
  • 1970-01-01
相关资源
最近更新 更多