C# Asp.Net Web API 中带有字典参数的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11950351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Method with Dictionary Parameter in Asp.Net Web API
提问by kkocabiyik
I need to make a GET request to a method that contains Dictionary as a parameter. I browse through but could not find any kinds of information about how I could send Dictionary so my request hit to my method. Method signature is as like as below
我需要向包含 Dictionary 作为参数的方法发出 GET 请求。我浏览但找不到任何关于如何发送字典的信息,所以我的请求命中了我的方法。方法签名如下
public void AddItems(Dictionary<string,object> Items)
Best Regards,
此致,
Kemal
凯末尔
采纳答案by Kirill Bestemyanov
回答by Kunal
You Can Use Dictionary As A Parameter In This Way:
您可以通过以下方式使用字典作为参数:
protected object DictionaryFunction()
{
Dictionary<int,YourObjectName> YourDictionaryObjectName=new Dictionary<int,YourObjectName>();
...
...
return YourDictionaryObjectName;
}
protected MyFunction()
{
Dictionary<int,YourObjectName> MyDictionary=(Dictionary<int,YourObjectName>)DictionaryFunction();
}
回答by Amir Yonatan
I wrote a ModelBinder that does exactly what you wanted:
我写了一个 ModelBinder,它完全符合你的要求:
public class DictionaryModelBinder : DefaultModelBinder
{
private const string _dateTimeFormat = "dd/MM/yyyy HH:mm:ss";
private enum StateMachine
{
NewSection,
Key,
Delimiter,
Value,
ValueArray
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stream = controllerContext.HttpContext.Request.InputStream;
string text;
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
int index = 0;
return Build(text, ref index);
}
private static Dictionary<string, object> Build(string text, ref int index)
{
var state = StateMachine.NewSection;
var dictionary = new Dictionary<string, object>();
var key = string.Empty;
object value = string.Empty;
for (; index < text.Length; ++index)
{
if (state == StateMachine.NewSection && text[index] == '{')
{
dictionary = new Dictionary<string, object>();
state = StateMachine.NewSection;
}
else if (state == StateMachine.NewSection && text[index] == '"')
{
key = string.Empty;
state = StateMachine.Key;
}
else if (state == StateMachine.Key && text[index] != '"')
{
key += text[index];
}
else if (state == StateMachine.Key && text[index] == '"')
{
state = StateMachine.Delimiter;
}
else if (state == StateMachine.Delimiter && text[index] == ':')
{
state = StateMachine.Value;
value = string.Empty;
}
else if (state == StateMachine.Value && text[index] == '[')
{
state = StateMachine.ValueArray;
value = value.ToString() + text[index];
}
else if (state == StateMachine.ValueArray && text[index] == ']')
{
state = StateMachine.Value;
value = value.ToString() + text[index];
}
else if (state == StateMachine.Value && text[index] == '{')
{
value = Build(text, ref index);
}
else if (state == StateMachine.Value && text[index] == ',')
{
dictionary.Add(key, ConvertValue(value));
state = StateMachine.NewSection;
}
else if (state == StateMachine.Value && text[index] == '}')
{
dictionary.Add(key, ConvertValue(value));
return dictionary;
}
else if (state == StateMachine.Value || state == StateMachine.ValueArray)
{
value = value.ToString() + text[index];
}
}
return dictionary;
}
private static object ConvertValue(object value)
{
string valueStr;
if (value is Dictionary<string, object> || value == null || (valueStr = value.ToString()).Length == 0)
{
return value;
}
bool boolValue;
if (bool.TryParse(valueStr, out boolValue))
{
return boolValue;
}
int intValue;
if (int.TryParse(valueStr, out intValue))
{
return intValue;
}
double doubleValue;
if (double.TryParse(valueStr, out doubleValue))
{
return doubleValue;
}
valueStr = valueStr.Trim('"');
DateTime datetimeValue;
if (DateTime.TryParseExact(valueStr, _dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out datetimeValue))
{
return datetimeValue;
}
if (valueStr.First() == '[' && valueStr.Last() == ']')
{
valueStr = valueStr.Trim('[', ']');
if (valueStr.Length > 0)
{
if (valueStr[0] == '"')
{
return valueStr
.Split(new[] { '"' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x != ",")
.ToArray();
}
else
{
return valueStr
.Split(',')
.Select(x => ConvertValue(x.Trim()))
.ToArray();
}
}
}
return valueStr;
}
}
More explanations and full post you can see in my blog:
您可以在我的博客中看到更多解释和完整帖子:
回答by Cubelaster
If you have problems receiving Dictionary in your webApi controller, relatively painless solution is to switch the parameter to List<"ObjectRepresentingDict"> insetead. It will map automatically.
如果您在 webApi 控制器中接收字典时遇到问题,相对轻松的解决方案是将参数切换到 List<"ObjectRepresentingDict"> insetead。它会自动映射。

