Calling a method with a Dictionary argument - c#

I have a method starting with this line
public string CustomerInfo(Dictionary<string, object> arglist)
I am trying to call it with this code
string testval = CustomerInfo(Dictionary< string, object>);
The error is
Dictionary is a type but used as a variable.
Thanks for any suggestions.

There's an issue in your code. The dictionary being passed is not initialized
you should try
String testval = CustomerInfo(new Dictionary< string, object>());
or
var dictionary = new Dictionary< string, object>();
string testval = CustomerInfo(dictionary);

You may do it this way
string testval = CustomerInfo(new Dictionary<string, object>());
C# 6 Dictionary Initializers
string testval = CustomerInfo(new Dictionary<string, object>() {
{ "1",1 } , {"2",2 }, {"3",new object() }
});
Or pass a dictionary object
var arglist = new Dictionary<string, object>() {
{ "1",1 } , {"2",2 }, {"3",new object() }
};
string testval = CustomerInfo(arglist);

Related

How to URL encode a dictionary in C# with bracket notation

Let's say I have the following class:
public class TestClass
{
public Dictionary<string, string> Property1 { get; set; }
}
If I do the following:
var dictionary = new Dictionary<string, string>();
dictionary.add("key1", "value1");
dictionary.add("key2", "value2");
var newClass = new TestClass();
newClass.Property1 = dictionary;
I am trying to URL encode this dictionary to the following:
https://baseaddress.com/resource/?Property1[key1]=value1&Property1[key2]=value2
When attempting to URL encode the dictionary via HttpUtility it is returning the ToString() method of the Dictionary which comes out as:
System.Collections.Generic.Dictionary`2[System.String,System.String]
I am trying to pass this dictionary to a .netcore API that binds to a similar Dictionary<string, string>
Edit
I was able to get it working by using the following code:
var builder = new UriBuilder(uri);
var query = HttpUtility.ParseQueryString(string.Empty);
foreach (var propInfo in obj.GetType().GetProperties())
{
var propName = propInfo.Name;
var propValue = propInfo.GetValue(obj);
if (propValue != null)
{
var dict = propValue as IDictionary;
if (dict != null)
{
foreach (var key in dict.Keys)
{
var keyName = key;
var keyValue = dict[key];
query.Add($"{propName}[{keyName}]", keyValue.ToString());
}
}
else
{
query.Add(propName, propValue.ToString());
}
}
}
builder.Query = query.ToString();
return builder.Uri;
I was hoping there was a more efficient way to make this work.
If you want to get the standard format and avoid any problem with your QueryString you can "leverage" .net core approach which indeed is a way larger than the old approach. With that said here is what you can do:
One thing....Notice that they are strings so you can add your brackets :)
Dictionary<String,StringValues>() queryString = QueryHelpers.ParseQuery("?param1=value");
StringValues secondValue=StringValues.Concat(queryString["param2"], "my other value");
parsedQueryString["yourkey"] = secondValue;
//At this point you can start concatenating as many time as needed.
QueryString.Create(parsedQueryString).ToString();
// creates the following string "?param1=value&param2=my%20other%20value"
A plus :)
// Getting a param value
var param2Value = queryString["param2"];
param2Value.ToString(); // Get the values concatenated together
param2Value.ToArray(); // Gets an array of strings
// Modifying a parameter
queryString["param1"] = "another value";
// NOTE, if there were two values, this overwrites both and leaves a single value

C# Equilavent of "dynamic" JavaScript object?

I want to create a single object (possibly Dictionary) with string keys that will have different variable types as the value (string, int, bool, Dictionary<string,string> etc). Is this possible?
*I understand this might just be a fundamental difference of two languages AKA square peg round hole
You can use dynamic as values type, that match better than object to the question and you need no future castings:
var dictionary = new Dictionary<string, dynamic>();
dictionary.Add("1", 10);
dictionary.Add("2", "test");
dictionary.Add("3", true);
foreach ( var item in dictionary )
Console.WriteLine($"{item.Key} is type: {item.Value.GetType().Name} = {item.Value}");
Console.WriteLine();
int v = dictionary["1"] + 10;
Console.WriteLine(v);
string s = dictionary["2"] + " one";
Console.WriteLine(s);
bool b = !dictionary["3"];
Console.WriteLine(b);
Output
1 is type: Int32 = 10
2 is type: String = test
3 is type: Boolean = True
20
test one
False
https://learn.microsoft.com/dotnet/csharp/programming-guide/types/using-type-dynamic
A Dictionary<string, object> is roughly equivalent to an object in JavaScript.
Example:
var dictionary = new Dictionary<string, object>
{
"myString" = "helloWorld",
"myChild" = new Dictionary<string, object>
{
"myName" = "bobby tables"
}
};
var myString = (string)dictionary["myString"];
var myName = (string)((Dictionary<string, object>)dictionary["myChild"])["myName"];
You can also use the dynamic keyword and ExpandoObject.
dynamic obj = new ExpandoObject();
obj.MyString = "helloWorld";
obj.MyChild = new ExpandoObject();
obj.MyChild.MyName = "bobby tables";
string myString = obj.MyString;
string myName = obj.MyChild.MyName;

dictionary to json with key names

I have a dictionary Dictionary<int, string> of ints and strings, where ints are ids and strings are usernames, and when I convert it to JSON using Json.NET I get something like the following:
{"3":"jack","2":"john"}
I convert it like so:
Dictionary<int, string> dictFriends = new Dictionary<int, string>();
foreach (var id in resultList)
{
var user = db.Users.Find(id);
string friend = user.Username;
dictFriends.Add(id, friend);
}
string json = JsonConvert.SerializeObject(dictFriends);
But I am hoping to get something like so:
[
{ "id": "3", "user": "jack"},
{ "id": "2", "user": "john"},
]
Is it possible?
As far as I know you'd have to transform the dictionary into something JSON.NET would recognise as being an IEnumerable:
// YOUR DICTIONARY
var dictFriends = new Dictionary<int, string>() {
{1,"Jack"},
{2,"John"},
{3,"Jeff"}
};
// TRANSFORM INTO IENUMERABLE
var transformed = from key in dictFriends.Keys
select new { id = key, user = dictFriends[key] };
// SERIALIZE
var json = JsonConvert.SerializeObject(transformed);
Output:
[
{"id":1, "user":"Jack"},
{"id":2, "user":"John"},
{"id":3, "user":"Jeff"}
]
You're trying to use a Dictionary as an Array/List, writing to an existing key will overwrite it. Also your current key type is int therefore you would have JSON output such as
{1: "jack", 2: "john"}
Instead set your object type to List<Dictionary<string, Object>>
List<Dictionary<string, object>> friends = new List<Dictionary<string, Object>>();
foreach (var id in resultList)
{
var user = db.Users.Find(id);
string friend = user.Username;
Dictionary<string, object> dictFriend = new Dictionary<string, Object>();
dictFriend.Add("id", id);
dictFriend.Add("name" , friend);
friends.Add(dictFriend);
}
string json = JsonConvert.SerializeObject(friends);
You could use the DataContractJsonSerializer: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer(v=vs.110).aspx
The below will produce output in the form you're after; only instead of id and user your fields would be named key and value. The reason being those are the property names on the dictionary.
If you needed to change those names also (i.e. it's not just the structure you're interested in), you'd need to override the dictionary with a custom class, where you could add attributes such as [JsonProperty(PropertyName = "User")] to the properties to change how they're parsed... See http://www.newtonsoft.com/json/help/html/SerializationAttributes.htm for more.
Dictionary<int, string> dictFriends = new Dictionary<int, string>();
dictFriends.Add(1, "Alice");
dictFriends.Add(2, "Bob");
string jsonString;
using (MemoryStream ms = new MemoryStream()) {
//NB: DataContractJsonSerializer is in assembly System.Runtime.Serialization.dll - and others; http://stackoverflow.com/a/2682197/361842
DataContractJsonSerializer dcjs = new DataContractJsonSerializer(dictFriends.GetType());
dcjs.WriteObject(ms, dictFriends);
ms.Position = 0;
using(StreamReader sr = new StreamReader(ms)) {
jsonString = sr.ReadToEnd();
}
}
Debug.WriteLine(jsonString);
Sample output:
[{"Key":1,"Value":"Alice"},{"Key":2,"Value":"Bob"}]

Neo4j + bolt + c#; how do you create multiple nodes via one query by passing a map as a parameter

can anyone advise how I should change my code (this is based on section 3.5.1.4.2 from the 3.0 developer manual). I am trying to create multiple nodes via one query in bolt.
using (var driver = GraphDatabase.Driver(Neo4jCredentials.Instance, AuthTokens.Basic(Neo4jCredentials.Username, Neo4jCredentials.Password)))
using (var session = driver.Session())
{
string query = "UNWIND { props } AS map CREATE(n) SET n = map";
Dictionary<string, object> myParameter = new Dictionary<string, object>();
myParameter.Add("props", "{\"props\":[{\"name\":\"Andres\",\"position\":\"Developer\"},{\"name\":\"Michael\",\"position\":\"Developer\"}]}");
return session.Run(query, myParameter);
}
The error I am getting is:
{"Expected map to be a map, but it was :`{\"props\":[{\"name\":\"Andres\",\"position\":\"Developer\"},{\"name\":\"Michael\",\"position\":\"Developer\"}]}`"}
Thanks in advance my learned friends...
Try forming your dictionary of params using an array of dictionaries:
Dictionary<string, object> myParameter = new Dictionary<string, object>();
Dictionary<string, object>[] props =
{
new Dictionary<string, object> {{"name", "Andres"}, {"position", "Developer"}},
new Dictionary<string, object> {{"name", "Michael"}, {"position", "Developer"}}
};
myParameter.Add("props",props);
or with a few less characters:
var myParameter = new Dictionary<string, object>
{
{
"props", new[]
{
new Dictionary<string, string> {{"name", "Andres"}, {"position", "Developer"}},
new Dictionary<string, string> {{"name", "Michael"}, {"position", "Developer"}}
}
}
};

How can I populate a NameValueCollection via a parameter in a shared method?

I have a code segment:
var requestMock = new Mock<HttpRequestBase>();
var queryString = new NameValueCollection();
queryString["abc"] = "123";
queryString["qwe"] = "456";
queryString["yui"] = "678";
...
requestMock.SetupGet(rqst => rqst.QueryString).Returns(queryString);
Now, I would like to have the above segment written as a method:
var requestMock = GetRequestMock(???);
I intend to send the query string key/values which can be anything.
And the count of k/v pairs also can be anything.
public Mock<HttpRequestBase> GetRequestMock(???)
{
var requestMock = new Mock<HttpRequestBase>();
....
requestMock.SetupGet(rqst => rqst.QueryString).Returns(queryString);
return requestMock;
}
What would be the best way to do this eficiently and simply?
One way would be to use a Dictionary:
public Mock<HttpRequestBase> GetRequestMock(Dictionary<string, object> queryParms)
{
var queryString = new NameValueCollection();
foreach (KeyValuePair<string, object> kvp in queryParms)
{
queryString[kvp.Key] = Convert.ToString(kvp.Value);
}
...
}
and then you can call it like this:
GetRequestMock(new Dictionary<string, object> { { "abc", "123" }, { "qwe", "456" } } );

Categories