C# 如何通过Refit和其他来源在Web API应用程序中传递字典作为查询参数?
我在将字典作为父对象的一部分作为查询参数传递时遇到了一个小问题 所以,我有一个方法可以得到一个FormulationParameters变量C# 如何通过Refit和其他来源在Web API应用程序中传递字典作为查询参数?,c#,dictionary,refit,C#,Dictionary,Refit,我在将字典作为父对象的一部分作为查询参数传递时遇到了一个小问题 所以,我有一个方法可以得到一个FormulationParameters变量 public async ValueTask<IActionResult> Get([FromQuery] FormulationParameters formulationParameters) { return Ok(await _service.Get(formulationParameters)); } 但是,没有效果,替代
public async ValueTask<IActionResult> Get([FromQuery] FormulationParameters formulationParameters)
{
return Ok(await _service.Get(formulationParameters));
}
但是,没有效果,替代品仍然没有被填充
另外,我尝试为这个属性编写一个自定义转换器,但没有效果,当请求到来时它甚至没有调用
唯一有效的是动作过滤器。我在StackOverflow帖子中找到了这个解决方案,在那里讨论了同样的问题。此筛选器中的方法如下所示:
public class FormulationParameters
{
//other simple properties, e.g. string, int
public Dictionary<string, string> Substitute { get; set; }
}
?Codes=Code1,Code2&Type=Type&Language=en&FirstValue=1&SecondValue=10
public override void OnActionExecuting(ActionExecutingContext context)
{
var notMatchedProperties = new Dictionary<string, string>();
// because in ActionArguments there is only one variable - formulationParameters
var mainVariableKey = context.ActionArguments.First().Key;
// the content of FormulationParameters class
var innerParts = context.ActionArguments.First().Value as FormulationParameters;
// conversion from class to dictionary
// the names of the properties are the keys, and their values are values in the dictionary
var classAsDictionary = ClassToDictionaryConverter.Convert(innerParts);
var keys = classAsDictionary.Keys;
foreach (var kvp in context.HttpContext.Request.Query)
{
if (!keys.Contains(kvp.Key, StringComparer.InvariantCultureIgnoreCase))
{
notMatchedProperties.Add(kvp.Key, kvp.Value);
}
}
// fill this dictionary with no matched properties from input
innerParts!.Substitute = notMatchedProperties;
// rewrite the existing value with the new value
context.ActionArguments[mainVariableKey] = innerParts;
base.OnActionExecuting(context);
}
public override void OnActionExecuting(ActionExecutingContext上下文)
{
var notMatchedProperties=新字典();
//因为在ActionArguments中只有一个变量——formulationParameters
var mainVariableKey=context.ActionArguments.First().Key;
//FormulationParameters类的内容
var innerParts=context.ActionArguments.First().Value作为FormulationParameters;
//从类到字典的转换
//属性的名称是键,它们的值是字典中的值
var classAsDictionary=ClassToDictionaryConverter.Convert(内部部件);
var keys=classAsDictionary.keys;
foreach(context.HttpContext.Request.Query中的var kvp)
{
如果(!keys.Contains(kvp.Key,StringComparer.InvariantCultureIgnoreCase))
{
添加(kvp.Key,kvp.Value);
}
}
//使用输入中不匹配的属性填充此词典
innerParts!.Substitute=notMatchedProperties;
//用新值重写现有值
ActionArguments[mainVariableKey]=内部部件;
base.OnActionExecuting(上下文);
}
这也不好,因为当我试图通过邮递员传递一些参数时,它不能正常工作。例如:Codes[0]=1&Codes[1]=2,但是当我这样写Codes=1&Codes=2时,它工作得很好-它被映射到代码:{1,2},并且它被认为像一个键Codes。而且,它不是通用的,看起来像是一种变通方法
我不知道是否可以使用这个动作过滤器,或者还有另一个我还没有尝试过的解决方案(但我不知道)。如果可以的话,我会使用这个过滤器,我的用户和我都需要记住如何正确传递这些参数。
因此,我正在寻找一种更通用的方法来解析来自不同来源(如Refit、Swagger、Postman)的请求时的这些参数
另外,我使用的是.NET5,我的应用程序是WebAPI类型
public override void OnActionExecuting(ActionExecutingContext context)
{
var notMatchedProperties = new Dictionary<string, string>();
// because in ActionArguments there is only one variable - formulationParameters
var mainVariableKey = context.ActionArguments.First().Key;
// the content of FormulationParameters class
var innerParts = context.ActionArguments.First().Value as FormulationParameters;
// conversion from class to dictionary
// the names of the properties are the keys, and their values are values in the dictionary
var classAsDictionary = ClassToDictionaryConverter.Convert(innerParts);
var keys = classAsDictionary.Keys;
foreach (var kvp in context.HttpContext.Request.Query)
{
if (!keys.Contains(kvp.Key, StringComparer.InvariantCultureIgnoreCase))
{
notMatchedProperties.Add(kvp.Key, kvp.Value);
}
}
// fill this dictionary with no matched properties from input
innerParts!.Substitute = notMatchedProperties;
// rewrite the existing value with the new value
context.ActionArguments[mainVariableKey] = innerParts;
base.OnActionExecuting(context);
}