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
public void AddItems(Dictionary<string,object> Items)
Best Regards,
Kemal
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Did you read ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries
Method 2
I wrote a ModelBinder that does exactly what you wanted:
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:
Json To Dictionary generic model binder
Method 3
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.
Method 4
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();
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0