我想将原始查询字符串作为控制器操作参数:
/// <summary>
/// Return filtered wire transfers
/// </summary>
[HttpGet("wire-transfers")]
[ProducesResponseType(typeof(LoadResult), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public Task<ActionResult<ProxyLoadResult>> GetAsync(
[BearerTokenFromHeader] string bearerToken,
[RawQueryString] string rawQueryString,
CancellationToken cancellationToken = default) =>
this.TryCatchRefitCallExceptionAsync(
() => _memberCreditorWireTransfersService
.GetAsync(bearerToken, rawQueryString, cancellationToken));
我遵循与BearerTokenFromHeaderAttribute
相同的逻辑:https://stackoverflow.com/a/59347840/4636721
RawQueryStringAttribute.cs
:
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class RawQueryStringAttribute : Attribute, IBindingSourceMetadata, IModelNameProvider
{
public BindingSource BindingSource =>
RawQueryStringBindingSource.Instance;
public string? Name { get; set; }
}
RawQueryStringBindingSource.cs
:
public static class RawQueryStringBindingSource
{
public const string Id = "RawQueryString";
public const string Name = Id;
public static readonly BindingSource Instance = new BindingSource(
Id,
Name,
isGreedy: false,
isFromRequest: true);
}
RawQueryStringValueProvider.cs
:
public class RawQueryStringValueProvider : BindingSourceValueProvider
{
public RawQueryStringValueProvider(BindingSource bindingSource, string rawQueryString) : base(bindingSource) =>
RawQueryString = rawQueryString;
private string RawQueryString { get; }
public override bool ContainsPrefix(string prefix) =>
false;
public override ValueProviderResult GetValue(string key) =>
string.IsNullOrEmpty(key)
? new ValueProviderResult(RawQueryString)
: ValueProviderResult.None;
}
RawQueryStringValueProviderFactory.cs
:
public class RawQueryStringValueProviderFactory : IValueProviderFactory
{
public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
{
var rawQueryString = context.ActionContext.HttpContext.Request?.QueryString.Value;
context.ValueProviders.Add(
new RawQueryStringValueProvider(RawQueryStringBindingSource.Instance,
rawQueryString!));
return Task.CompletedTask;
}
}
但是当控制器动作通过类似这样的方式调用时:
http://localhost:5000/api/v1/wire-transfers?requireTotalCount=true&skip=0&take=5
我收到以下错误:
{
"errors":{
"rawQueryString":[
"The rawQueryString field is required."
]
},
"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title":"One or more validation errors occurred.",
"status":400,
"traceId":"|dd22ddb4-44ebc27fb1cbc9ba."
}
不确定是否真的明白为什么,有什么想法吗?
如果要这样做也要避免任何误解:
/// <summary>
/// Return filtered wire transfers
/// </summary>
[HttpGet("wire-transfers")]
[ProducesResponseType(typeof(LoadResult), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public Task<ActionResult<ProxyLoadResult>> GetAsync(
[BearerTokenFromHeader] string bearerToken,
CancellationToken cancellationToken = default) =>
this.TryCatchRefitCallExceptionAsync(
() => _memberCreditorWireTransfersService
.GetAsync(bearerToken, this.Request.QueryString.Value, cancellationToken));
相同的请求很好用...
我的意思是我只想将this.Request.QueryString.Value
作为控制器操作参数。