ASP.NET Web Api 2 post 请求来自 Uri 和来自正文
ASP.NET Web Api 2 post request From Uri and From Body
我有一个 ASP.NET Web Api 2 端点,供不同的客户端使用。端点应该接受来自 body 和 Uri 的发布数据。
所以我的问题是,我的 POST 操作是否可以支持这两种类型的请求并将发布的数据映射到 POST 操作中?
我对该问题的解决方案是公开两个端点 - 一个支持每个场景(请参阅下面的代码),但我宁愿只有一个端点可以提供给所有客户端。怎么可能?
// The Controller Action when data is posted in the Uri:
// POST: api/PostUri
[HttpPost]
[ActionName("PostUri")]
public Result Post([FromUri]Data data)
{
// Do something..
}
// The Controller Action when request is posted with data in the Body:
// POST: api/MyController/PostBody
[HttpPost]
[ActionName("PostBody")]
public Result PostBody(Data data)
{
return Post(data);
}
您可以通过自定义实施 HttpParameterBinding
来实现您的目标。这是此类活页夹的工作示例:
public class UriOrBodyParameterBinding : HttpParameterBinding
{
private readonly HttpParameterDescriptor paramDescriptor;
public UriOrBodyParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor)
{
paramDescriptor = descriptor;
}
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext,
CancellationToken cancellationToken)
{
HttpParameterBinding binding = actionContext.Request.Content.Headers.ContentLength > 0
? new FromBodyAttribute().GetBinding(paramDescriptor)
: new FromUriAttribute().GetBinding(paramDescriptor);
await binding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
}
}
我们检查 Content-Length
HTTP header 以找出请求是否包含 http body。如果是,我们从 body 绑定模型。否则模型从 Url.
绑定
您还应该添加自定义属性以标记将使用此自定义活页夹的操作参数:
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class FromUriOrBodyAttribute : Attribute
{
}
这是应该添加到 WebApiConfig.Register()
方法中的活页夹注册。我们检查动作参数是否标有 FromUriOrBodyAttribute
并在这种情况下使用我们的自定义活页夹:
config.ParameterBindingRules.Insert(0, paramDesc =>
{
if (paramDesc.GetCustomAttributes<FromUriOrBodyAttribute>().Any())
{
return new UriOrBodyParameterBinding(paramDesc);
}
return null;
});
现在您可以有一个 Post 操作来绑定来自请求 body 或 Url 的模型:
[HttpPost]
public void Post([FromUriOrBody] Data data)
{
// ...
}
我可以通过让我的 Controller
Action
使用两个参数来解决它。我的数据类型的两个参数 - 一个带有 [FromUri]
属性,一个没有:
public Result Post([FromUri]Data fromUri, Data fromBody)
{
// Check fromUri and its properties
// Check fromBody and its properties
...
}
如果数据的 Request
放在正文中,数据将绑定到 fromBody
参数。如果 Request
数据在 URI 中,那么它们将使用 [FromUri]
属性绑定到 fromUri
参数。
我有一个 ASP.NET Web Api 2 端点,供不同的客户端使用。端点应该接受来自 body 和 Uri 的发布数据。 所以我的问题是,我的 POST 操作是否可以支持这两种类型的请求并将发布的数据映射到 POST 操作中?
我对该问题的解决方案是公开两个端点 - 一个支持每个场景(请参阅下面的代码),但我宁愿只有一个端点可以提供给所有客户端。怎么可能?
// The Controller Action when data is posted in the Uri:
// POST: api/PostUri
[HttpPost]
[ActionName("PostUri")]
public Result Post([FromUri]Data data)
{
// Do something..
}
// The Controller Action when request is posted with data in the Body:
// POST: api/MyController/PostBody
[HttpPost]
[ActionName("PostBody")]
public Result PostBody(Data data)
{
return Post(data);
}
您可以通过自定义实施 HttpParameterBinding
来实现您的目标。这是此类活页夹的工作示例:
public class UriOrBodyParameterBinding : HttpParameterBinding
{
private readonly HttpParameterDescriptor paramDescriptor;
public UriOrBodyParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor)
{
paramDescriptor = descriptor;
}
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext,
CancellationToken cancellationToken)
{
HttpParameterBinding binding = actionContext.Request.Content.Headers.ContentLength > 0
? new FromBodyAttribute().GetBinding(paramDescriptor)
: new FromUriAttribute().GetBinding(paramDescriptor);
await binding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
}
}
我们检查 Content-Length
HTTP header 以找出请求是否包含 http body。如果是,我们从 body 绑定模型。否则模型从 Url.
您还应该添加自定义属性以标记将使用此自定义活页夹的操作参数:
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class FromUriOrBodyAttribute : Attribute
{
}
这是应该添加到 WebApiConfig.Register()
方法中的活页夹注册。我们检查动作参数是否标有 FromUriOrBodyAttribute
并在这种情况下使用我们的自定义活页夹:
config.ParameterBindingRules.Insert(0, paramDesc =>
{
if (paramDesc.GetCustomAttributes<FromUriOrBodyAttribute>().Any())
{
return new UriOrBodyParameterBinding(paramDesc);
}
return null;
});
现在您可以有一个 Post 操作来绑定来自请求 body 或 Url 的模型:
[HttpPost]
public void Post([FromUriOrBody] Data data)
{
// ...
}
我可以通过让我的 Controller
Action
使用两个参数来解决它。我的数据类型的两个参数 - 一个带有 [FromUri]
属性,一个没有:
public Result Post([FromUri]Data fromUri, Data fromBody)
{
// Check fromUri and its properties
// Check fromBody and its properties
...
}
如果数据的 Request
放在正文中,数据将绑定到 fromBody
参数。如果 Request
数据在 URI 中,那么它们将使用 [FromUri]
属性绑定到 fromUri
参数。