我在此处发布了关于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; }
}
}
}
答案 0 :(得分:0)
您需要实现自己的属性和活页夹。
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);
}