How can I get the dictionary value by a key on a function?
My function code (and the command I try doesn't work):
static void XML_Array(Dictionary<string, string> Data_Array)
{
String xmlfile = Data_Array.TryGetValue("XML_File", out value);
}
My button code:
private void button2_Click(object sender, EventArgs e)
{
Dictionary<string, string> Data_Array = new Dictionary<string, string>();
Data_Array.Add("XML_File", "Settings.xml");
XML_Array(Data_Array);
}
I want on the XML_Array function the variable to be:
string xmlfile = "Settings.xml":
It's as simple as this:
String xmlfile = Data_Array["XML_File"];
Note that if the dictionary doesn't have a key that equals "XML_File", that code will throw an exception. If you want to check first, you can use TryGetValue like this:
string xmlfile;
if (!Data_Array.TryGetValue("XML_File", out xmlfile)) {
// the key isn't in the dictionary.
return; // or whatever you want to do
}
// xmlfile is now equal to the value
Just use the key name on the dictionary. C# has this:
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("UserID", "test");
string userIDFromDictionaryByKey = dict["UserID"];
If you look at the tip suggestion:
That is not how the TryGetValue works. It returns true or false based on whether the key is found or not, and sets its out parameter to the corresponding value if the key is there.
If you want to check if the key is there or not and do something when it's missing, you need something like this:
bool hasValue = Data_Array.TryGetValue("XML_File", out value);
if (hasValue) {
xmlfile = value;
} else {
// do something when the value is not there
}
Dictionary<String, String> d = new Dictionary<String, String>();
d.Add("1", "Mahadev");
d.Add("2", "Mahesh");
Console.WriteLine(d["1"]); // It will print Value of key '1'
static void XML_Array(Dictionary<string, string> Data_Array)
{
String value;
if(Data_Array.TryGetValue("XML_File", out value))
{
// ... Do something here with value ...
}
}
static String findFirstKeyByValue(Dictionary<string, string> Data_Array, String value)
{
if (Data_Array.ContainsValue(value))
{
foreach (String key in Data_Array.Keys)
{
if (Data_Array[key].Equals(value))
return key;
}
}
return null;
}
Here is an example which I use in my source code.
I am getting key and value from Dictionary from element 0 to number of elements in my Dictionary. Then I fill my string[] array which I send as a parameter after in my function which accept only params string[]
Dictionary<string, decimal> listKomPop = addElements();
int xpopCount = listKomPop.Count;
if (xpopCount > 0)
{
string[] xpostoci = new string[xpopCount];
for (int i = 0; i < xpopCount; i++)
{
/* here you have key and value element */
string key = listKomPop.Keys.ElementAt(i);
decimal value = listKomPop[key];
xpostoci[i] = value.ToString();
}
...
This solution works with SortedDictionary also.
Dictionary<int,string> dict = new Dictionary<int,string>{
{1,"item1"},
{2,"item2"},
{3,"item3"},
}
int key = 2 // for example
string result = dict.ContainsKey(key) ? dict[key] : null;
private void button2_Click(object sender, EventArgs e)
{
Dictionary<string, string> Data_Array = new Dictionary<string, string>();
Data_Array.Add("XML_File", "Settings.xml");
XML_Array(Data_Array);
}
static void XML_Array(Dictionary<string, string> Data_Array)
{
String xmlfile = Data_Array["XML_File"];
}
I use a similar method to dasblinkenlight's in a function to return a single key value from a Cookie containing a JSON array loaded into a Dictionary as follows:
/// <summary>
/// Gets a single key Value from a Json filled cookie with 'cookiename','key'
/// </summary>
public static string GetSpecialCookieKeyVal(string _CookieName, string _key)
{
//CALL COOKIE VALUES INTO DICTIONARY
Dictionary<string, string> dictCookie =
JsonConvert.DeserializeObject<Dictionary<string, string>>
(MyCookinator.Get(_CookieName));
string value;
if (dictCookie.TryGetValue( _key, out value))
{
return value;
}
else
{
return "0";
}
}
Where "MyCookinator.Get()" is another simple Cookie function getting an http cookie overall value.
(I posted this on another question and I don't know how to link to that so here it is)
A Dictionary<K,V> extension that works. I have been using it for a long time::
public static bool TryGetKey<K, V>(this IDictionary<K, V> instance, V value, out
K key)
{
foreach (var entry in instance)
{
if (!entry.Value.Equals(value))
{
continue;
}
key = entry.Key;
return true;
}
key = default(K);
return false;
}
And use as :
public static void Main()
{
Dictionary<string, string> dict = new Dictionary<string, string>()
{
{"1", "one"},
{"2", "two"},
{"3", "three"}
};
string value="two";
if (dict.TryGetKey(value, out var returnedKey))
Console.WriteLine($"Found Key {returnedKey}");
else
Console.WriteLine($"No key found for value {value}");
}
if (Data_Array["XML_File"] != "") String xmlfile = Data_Array["XML_File"];
Related
I have a function for stock many string associate to int:
public int Scale(string value)
{
this.stringToInt = new Dictionary<string, int>()
{
{"1p",00},{"2p",01},{"3p",03} ... {"300p",40}
};
// Here i try to do something like that: if(value == (String in dictionary) return associate int
}
So i try to do a comparaison between string receive in enter and string in my dictionary for return associate int.
Any idea?
Thanks you for help !
You can use ContainsKey() method of Dictionary to check if the key is present in dictionary:
if (this.stringToInt.ContainsKey(value)
{
return this.stringToInt[value];
}
else
{
// return something else
}
Another way is to use TryGetValue():
var valueGot = this.stringToInt.TryGetValue(value, out var associate);
if (valueGot)
{
return associate;
}
else
{
// return something else
}
I have an HttpContext.Request object that has data in the Form that is wrong and I want to fix it up and send the correct HttpContext on its way.
HttpContext.Request.Form is readonly, but if it wasn't I would have simply done the following;
HttpContext.Request.Form["a"] = "the correct value for a";
So, where is the best place in the pipeline to do this.
Is it possible to make the HttpContext.Request.Form write accessable via reflection?
This was easier than I thought. I am doing this in my middleware which is there to correct bad form data that came in.
public async Task Invoke(HttpContext context)
{
....
NameValueCollection fcnvc = context.Request.Form.AsNameValueCollection();
fcnvc.Set("a", "the correct value of a");
fcnvc.Set("b", "a value the client forgot to post");
Dictionary<string, StringValues> dictValues = new Dictionary<string, StringValues>();
foreach (var key in fcnvc.AllKeys)
{
dictValues.Add(key, fcnvc.Get(key));
}
var fc = new FormCollection(dictValues);
context.Request.Form = fc;
....
await _next.Invoke(context);
}
Interestingly the FormCollection is readonly, but the HttpContext.Request object is not thus allowing me to replace the entire Form.
Here's a .NET Core/5 solution that worked for me without using the Identity Server package.
Basically you build a new dictionary of type <string, StringValues> out of the existing form collection, modify the values in the dictionary how you want, then create a new FormCollection from that dictionary and set it to context.Request.Form. The important thing to remember is that the value which is of type StringValues is just an array of strings!
This example demonstrates me removing a "client_id" field from the request form.
var formDictionary = new Dictionary<string, StringValues>();
var form = context.Request.Form;
foreach (var key in form.Keys)
{
// Only add if key is NOT client_id
if (key != "client_id")
{
form.TryGetValue(key, out StringValues formValues);
formDictionary.Add(key, formValues);
}
}
FormCollection formCollection = new FormCollection(formDictionary);
context.Request.Form = formCollection;
Here is another example of me changing the "client_id" field to "NewValue"
var formDictionary = new Dictionary<string, StringValues>();
var form = context.Request.Form;
foreach (var key in form.Keys)
{
form.TryGetValue(key, out StringValues formValues);
// Change client_id value to "NewValue"
if (key == "client_id")
{
formValues = new string[] { "NewValue" };
}
formDictionary.Add(key, formValues);
}
FormCollection formCollection = new FormCollection(formDictionary);
context.Request.Form = formCollection;
AsNameValueCollection is inside of IdentityServer4.dll.
public static class IReadableStringCollectionExtensions
{
[DebuggerStepThrough]
public static NameValueCollection AsNameValueCollection(this IDictionary<string, StringValues> collection)
{
NameValueCollection values = new NameValueCollection();
foreach (KeyValuePair<string, StringValues> pair in collection)
{
string introduced3 = pair.get_Key();
values.Add(introduced3, Enumerable.First<string>(pair.get_Value()));
}
return values;
}
[DebuggerStepThrough]
public static NameValueCollection AsNameValueCollection(this IEnumerable<KeyValuePair<string, StringValues>> collection)
{
NameValueCollection values = new NameValueCollection();
foreach (KeyValuePair<string, StringValues> pair in collection)
{
string introduced3 = pair.get_Key();
values.Add(introduced3, Enumerable.First<string>(pair.get_Value()));
}
return values;
}
}
I personally prefer to use an extended method to do this.
public static IFormCollection PushToForm(this IFormCollection form, Dictionary<string, StringValues> data)
{
var formDictionary = new Dictionary<string, StringValues>();
foreach (var k in form.Keys)
{
form.TryGetValue(k, out StringValues v);
formDictionary.Add(k, v);
}
foreach (var x in data) formDictionary.Add(x.Key, x.Value);
return new FormCollection(formDictionary);
}
Example:
Request.Form = Request.Form.PushToForm(new Dictionary<string, StringValues>()
{
{ "key1", new string[] { "value1" } },
{ "key2", new string[] { "value2" } },
{ "key3", new string[] { "value3" } },
...
});
A bit complex but shorter solution
var collection = HttpContext.Request.Form;
var propInfo = collection.GetType().GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
propInfo.SetValue(collection, false, new object[]{});
collection.Remove("a");
collection.Add("a", "the correct value for a");
System.Diagnostics.Debug.Write(HttpContext.Request["a"]); // the correct value for a
Enjoy!
Hello I came up with situation where I am taking value from user in the form of querystring.
Name of first 2 parameter is fix,so name name of querystring is fix.After these 2 parameter,user may enter or may not enter any parameter.Parameter count can be from 1 to many and vary in datatype.
Ex: sitename/sample.aspx?username=''&userid=''&Date=
Ex: sitename/sample.aspx?username=''&userid=''&Date=&amount=
That's why I created dictionary object and storing key and value of dynamic querystring into it(not username and userid).
Dictionary<string, string> queryStringValues = new Dictionary<string, string>();
foreach (string key in Request.QueryString.AllKeys)
{
queryStringValues.Add(key, Request.QueryString[key]);
}
Here I have created dictionary of <string,string> .But my key must be string and value may not string. It can be int,date .How to take that?
At last I want to check datatype of value? How to do that?
Query string as the name says it's a string ( a collection of key value pair that consists of 2 strings ( key and value ) ) so basically you cannot know for sure if value of Date would be convertible to DateTime object.
You can though make something like factory ( which I've done few months ago ) to pair key with different Type.
To explain this in more detail :
public static class Factory
{
static Dictionary<string, Type> _fac = new Dictionary<string, Type>();
public static void Assign<T>(string key)
{
if(_fac.ContainsKey(key))
{
if(_fac[key] != typeof(T)) _fac[key] = typeof(T);
}
else
{
_fac.Add(key, typeof(T));
}
}
public static object Retrieve(string key, string value)
{
if(_fac.ContainsKey(key))
{
if(_fac[key] == typeof(string))
return value;
TypeConverter converter = TypeDescriptor.GetConverter(_fac[key]);
if(converter.CanConvertFrom(typeof(string))
return converter.ConvertFromString(value);
}
return null;
}
public static Type TypeFor(string key)
{
if(_fac.ContainsKey(key))
return _fac[key];
return null;
}
}
To use this simply do something like :
Factory.Assign<DateTime>("date");
// later on, you can retrieve value using this:
// assume query is "Date=01/01/2001"
Dictionary<string, object> queryStringValues = new Dictionary<string, object>();
foreach (string key in Request.QueryString.AllKeys)
{
queryStringValues.Add(key, Factory.Retrieve(key, Request.QueryString[key]));
}
You could use Dictionary with objects.
Dictionary<string, object> queryStringValues = new Dictionary<string, object>();
Note, after that ou should cast your objects to knwon type , something as:
queryStringValues.Add("2", true);
...
var q = queryStringValues["2"];
if (q is bool)
{
var r = !(bool)q;
}
Good day,
I need to make function that will iterate on Dictionary that stores variable name and variable`s new value. After that, I need to update class variable with that value.
void UpdateValues(Type type, Dictionary<string, string> values)
{
foreach (var value in values)
{
var fieldInfo = selected.GetComponent(type).GetType().GetField(value.Key);
if (fieldInfo == null) continue;
fieldInfo.SetValue(selected.GetComponent(type), value.Value);
}
}
It works but I want little improvement and I absolutely don't know if it is possible.
As you can see, that function can accept any class, not just one specific.
If I have class like this
class test
{
public string age;
}
And I would use function this way, it would work.
UpdateValues(typeof(test), new Dictionary<string, string>{{"age", "17"}});
Problem is if I have class like this and I would like to update "subfield" (field in field)
class test
{
public string age;
}
class test2
{
public test data;
}
I was thinking that syntax could be something like this, but I have no idea how could I do it.
UpdateValues(typeof(test2), new Dictionary<string, string>{{"data.age", "17"}});
To sum it up, I need to make function that will take class that is stored in another class. Function will iterate trough the dictionary and update fields of class and even her subfields.
I would propose to add a recursive call to your method, to set the properties. I have changed your method a little bit, because i don't have selected object, it takes an object as a parameter
void UpdateValues<T>(T obj, Dictionary<string, string> values)
{
foreach (var value in values)
{
SetProperty(obj, value.Key, value.Value);
}
}
public void SetProperty<T>( T obj, string valueKey, string value, Type type= null)
{
var typeToUse = type ?? typeof(T);
var pointIndex = valueKey.IndexOf(".");
if (pointIndex!=-1)
{
var subKey = valueKey.Substring(0, pointIndex);
var fieldInfo = typeToUse.GetField(subKey);
var propObj = fieldInfo.GetValue(obj)
?? Activator.CreateInstance(fieldInfo.FieldType);
SetProperty(propObj, valueKey.Substring(pointIndex+1), value, fieldInfo.FieldType);
fieldInfo.SetValue(obj, propObj);
}
else
{
var fieldInfo = typeToUse.GetField(valueKey);
if (fieldInfo != null)
fieldInfo.SetValue(obj, value);
}
}
It works even if you define
class test3
{
public test2 data;
}
and call
UpdateValues(t, new Dictionary<string, string>{{"age", "17"}});
UpdateValues(t2, new Dictionary<string, string> { { "data.age", "17" } });
UpdateValues(t3, new Dictionary<string, string> { { "data.data.age", "17" } });
The third parameter of SetProperty method is not really nice, i would avoid it, but i don't know how to solve it with generics, after creating with Activator you get object as a Type, and object doesn't have field age
You are using Dictionary<string, string> as a parameter that allows you to set only string fields, so you must assume that you don't have any other. Actually this will work even if you will use Dictionary<string, object>, that i would suggest to do.
First of all you will need to change your Dictionary variable to use
Dictionary<string, object> if you want to pass a class as a parameter in here.
Secondly Here is an example of how to make it work.
class test
{
public string age;
}
class test2
{
public test data;
}
Lets suppose i have created an instance of test class and added it in a dictionary, to get the fields with reflection and then update the instance of test2 accordingly.
public void UpdateValues(object test2, Dictionary<string, object> dict)
{
var fieldValues = test2.GetType()
.GetFields()
.ToList();
foreach (var value in dict)
{
foreach (var field in fieldValues)
{
if (value.Key == field.Name)
{
bool obj = field.FieldType == typeof(test);
if (obj)
{
if (dict.ContainsKey("data"))
{
var prop = test2.GetType().GetField("data", System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.Instance);
prop.SetValue(test2, dict["data"]);
break;
}
}
else
{
var prop = test2.GetType().GetField(value.Key, System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.Instance);
prop.SetValue(test2, value.Value);
break;
}
}
}
}
}
In the end call you function i have created a Dictionary<string,object> instance to send it as a parameter to the function
object test2 = new test2();
test t = new test();
t.age = "10";
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("data", t);
UpdateValues(test2, dict);
Currently my Dictionary<string, string> is serialized as:
{
"Uri" : "/site/Default.aspx",
"time-taken" : "232"
}
I would like Json.net to serialize it as
{
"Uri" : "/site/Default.aspx",
"time-taken" : 232
}
What would be the easiest way to achieve this with Json.net? I don't want to make a new class with the correct types instead of the Dictionary since the keys are many and may change. I know the keys that will be int.
I think I would just make a helper method that copied the data from a dictionary to a JObject like this:
public static class JsonHelper
{
public static string SerializeDictionary(Dictionary<string, string> dict, IEnumerable<string> intKeys)
{
JObject obj = new JObject();
foreach (var kvp in dict)
{
int intValue;
if (intKeys.Contains(kvp.Key) && int.TryParse(kvp.Value, out intValue))
obj.Add(kvp.Key, intValue);
else
obj.Add(kvp.Key, kvp.Value);
}
return obj.ToString(Formatting.Indented);
}
}
Then use it like this:
var dict = new Dictionary<string, string>();
dict.Add("AnInt", "123");
dict.Add("AString", "abc");
dict.Add("AnotherInt", "456");
dict.Add("KeepThisAsString", "789");
dict.Add("NotAnInt", "xyz");
var intKeys = new string[] { "AnInt", "AnotherInt" };
string json = JsonHelper.SerializeDictionary(dict, intKeys);
Console.WriteLine(json);
Output:
{
"AnInt": 123,
"AString": "abc",
"AnotherInt": 456,
"KeepThisAsString": "789",
"NotAnInt": "xyz"
}
Fiddle: https://dotnetfiddle.net/xdnnb0