asp.net-core - 带有 OData 的 aspnet Core 中的自定义参数绑定属性
问题描述
我在这里发布了关于 Ricks “原始请求正文”属性的实现...
...我正在将解决方案转换为.Net Core ...
有谁知道如何在 aspNet Core 中实现这一点作为 OData 控制器参数的绑定属性?
编辑:
万一它对任何人有帮助,这是我要转换的代码...
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Core.Api
{
/// <summary>
/// An attribute that captures the entire content body and stores it
/// into the parameter of type byte[].
/// </summary>
/// <remarks>
/// The parameter marked up with this attribute should be the only parameter as it reads the
/// entire request body and assigns it to that parameter.
/// </remarks>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public sealed class RawBodyAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
if (parameter == null) throw new ArgumentException("Invalid parameter");
return new RawBodyParameterBinding(parameter);
}
}
public class RawBodyParameterBinding : HttpParameterBinding
{
public RawBodyParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor) { }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
{
var binding = actionContext.ActionDescriptor.ActionBinding;
if(binding.ParameterBindings.Count(pb => pb.GetType() == typeof(RawBodyParameterBinding)) != 1)
throw new InvalidOperationException("Exactly one parameter must be marked with the RawBody attribute in the action signature.");
var type = binding.ParameterBindings.First(pb => pb.GetType() == typeof(RawBodyParameterBinding)).Descriptor.ParameterType;
if (type == typeof(string))
{
return actionContext.Request.Content
.ReadAsStringAsync()
.ContinueWith((task) => SetValue(actionContext, task.Result));
}
else if(type == typeof(byte[]))
{
return actionContext.Request.Content
.ReadAsByteArrayAsync()
.ContinueWith((task) => SetValue(actionContext, task.Result));
}
throw new InvalidOperationException("Only byte[] or string values are supported for [RawBody] parameters");
}
public override bool WillReadBody
{
get { return true; }
}
}
}
解决方案
您需要实现自己的属性和活页夹。
RawBodyAttribute
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class RawBodyAttribute : Attribute, IBindingSourceMetadata { public BindingSource BindingSource => RawBodyBindingSource.RawBody; }
RawBodyBindingSource
public class RawBodyBindingSource : BindingSource { public static readonly BindingSource RawBody = new RawBodyBindingSource( "RawBody", "RawBody", true, true ); public RawBodyBindingSource(string id, string displayName, bool isGreedy, bool isFromRequest) : base(id, displayName, isGreedy, isFromRequest) { } public override bool CanAcceptDataFrom(BindingSource bindingSource) { return bindingSource == Body || bindingSource == this; } }
RawBodyModelBinder
public class RawBodyModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { using (StreamReader reader = new StreamReader(bindingContext.HttpContext.Request.Body, Encoding.UTF8)) { var model = reader.ReadToEnd(); bindingContext.Result = ModelBindingResult.Success(model); } return Task.CompletedTask; } }
RawBodyModelBinderProvider
public class RawBodyModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context.BindingInfo.BindingSource != null && context.BindingInfo.BindingSource.CanAcceptDataFrom(RawBodyBindingSource.RawBody)) { return new RawBodyModelBinder(); } else { return null; } } }
登记
services.AddMvc(options => { options.ModelBinderProviders.Insert(0, new RawBodyModelBinderProvider()); }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
用例
public IActionResult Post([RawBody]string value) { return Ok(value); }
推荐阅读
- c# - 让插件使用 .NET Core 3.1 中使用 MEF 的旧版本程序集
- r - 使用 for 循环创建绘图列表
- python - 使用 Word2Vec 进行文本分类
- java - Spring Security JWT - 通过授权标头的邮递员身份验证有效,但从我的 Angular 前端不起作用
- python - 如何更新列表值,匹配另一个列表
- python - matplotlib 中的散点图和组合极坐标直方图
- r - 如何根据最后一次出现自动填充字符串
- php - PHP禁用输出缓冲
- angular - Angular 功能模块 dragdropmodule 未知属性
- linux - Terraform错误运行shell脚本时替换错误