gpt4 book ai didi

c# - WebAPI 自动绑定(bind)另一个参数

转载 作者:太空狗 更新时间:2023-10-30 01:17:58 24 4
gpt4 key购买 nike

在 MVC 中,这类事情非常微不足道。假设我有一个 MVC Action 签名:

public ActionResult SomeAction(InjectedObject a, ConstructedObject b)

假设来自客户端的请求包含 ConstructedObject,我想在框架管道中自动构建 InjectedObject。 (在这个例子中,InjectedObject 有很多操作,甚至可能是所有操作。)我可以创建一个 InjectedObjectModelBinder : IModelBinder 并在应用程序启动。

该 Binder 将简单地构造一个 InjectedObject 的实例,但我需要这样做。 (来自请求数据、来自其他来源、来源的组合等)这对于横切关注点非常有效。


但是,在 WebAPI 中有没有办法做到这一点?有一个新的 IModelBinder,但它的使用似乎假定输入只有一个模型。到目前为止,我的谷歌搜索也指出了这个假设。在 WebAPI 中,是否有可能像这样将某些东西作为横切关注点注入(inject)管道,同时仍然拥有来自帖子正文的构造模型?

这里的具体用例是我想构建一个自定义的授权相关对象,在本例中来自请求 header 。我可以在 Action 中构建它,但每个 Action 都需要这样做。我可以在 Controller 上添加一个扩展方法,但这会损害单元测试。首选方法是简单地将其注入(inject)管道,这样我就可以在对 Controller 操作进行单元测试时注入(inject)模拟。

WebAPI 支持吗?或者是否有另一种首选方法?

最佳答案

是的,您可以按照您建议的方式使用 IModelBinder,只需确保模型绑定(bind)器(仅)处理您的 InjectedObject。例如,下面的简单模型 Binder 读取标题“your_key”:

public class InjectedObjectModelBinder : IModelBinder
{
public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(InjectedObject))
{
return false;
}

IEnumerable<string> values;
string keyValue = "";

if (actionContext.Request.Headers.TryGetValues("your_key", out values))
{
keyValue = values.First();
}

bindingContext.Model = new InjectedObject() { Id = 789, Name = keyValue };

return true;
}
}

然后您需要将 Binder 连接到 InjectedObject 类。有几种方法可以做到这一点:首先,您可以在每个操作方法上执行此操作:

public void Post([ModelBinder(typeof(InjectedObjectModelBinder))]InjectedObject a, ConstructedObject b)

但鉴于您想在许多地方使用它,这感觉不对。其次,您可以通过使用 ModelBinder 属性装饰 InjectedObject 类来实现:

[ModelBinder(typeof(InjectedObjectModelBinder))]
public class InjectedObject
{....

最后,您可以将它添加到 WebApiConfig 类的 Register 方法中的 HttpConfiguration:

var provider = new SimpleModelBinderProvider(typeof(InjectedObject), new InjectedObjectModelBinder());
config.Services.Insert(typeof(ModelBinderProvider), 0, provider);

给定一些简单的 ConstructedObjectInjectedObject 实现以及上面的 Binder :

[ModelBinder(typeof(InjectedObjectModelBinder))]
public class InjectedObject
{
public int Id { get; set; }
public string Name { get; set; }
}

public class ConstructedObject
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}

和这样的操作方法:

public void Post(InjectedObject a, ConstructedObject b)
{
//a will be populated in our model binder.
}

最后是来自 Fiddler 的请求,如下所示:

POST http://localhost:64577/api/values HTTP/1.1
Host: localhost:64577
Accept: */*
Content-Type: application/json
Connection: keep-alive
Content-Length: 51
your_key: This came from the header

{"a":1,"b":2,"c":"This was 'normal' model binding"}

绑定(bind)的行为符合您的预期/希望:

Watch window with correctly bound values

可以找到一篇关于 Web API 中模型绑定(bind)的好文章 here .

关于c# - WebAPI 自动绑定(bind)另一个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29491849/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com