Convert query string dictionary (or associative array) to dictionary [duplicate] - c#

This question already has answers here:
How to parse a query string into a NameValueCollection in .NET
(19 answers)
Closed 5 years ago.
I'm trying to accept a query string of the form
?param[key1]=value1&param[key2]=value2
and convert it into a Dictionary in C# MVC 4. This is trivial to do in PHP, but I haven't been able to find any method of reproducing this in C#.
I know I can take an array via
?param=value1&param=value2
but that leaves issues of ordering and isn't nearly as useful for my purposes.
In the hopes that this isn't a limitation of the framework, how might I implement a dictionary-style conversion in C#?
To clarify: I'm not looking to convert a query string into an NVC, but rather to convert query string parameters into their own NVCs. This is NOT as simple as ParseQueryString() or the Request.QueryString object.

Can't you just use the Request.QueryString collection that Asp.Net provides for you? Since you are using MVC, it will be on your controllers ControllerContext property (located on that object's HttpContext property).

here I fixed some code that will work for you, defo not the best solutioin but it should work.
string basestring = "?param[key1]=value1&param[key2]=value2";
string newstring = basestring.Replace("?", "").Replace("param[", "").Replace("]", "");
var array = newstring.Split('&');
var dictionary = new Dictionary<string, string>();
foreach (var onestring in array)
{
var splitedstr = onestring.Split('=');
dictionary.Add(splitedstr[0],splitedstr[1]);
}

You can also try something like this
public ActionResult SubmitFormWithFormCollection(FormCollection parameters)
{
foreach (string param in parameters)
{
ViewData[param] = parameters[param];
}
return View();
}

Related

Any way to add arrays into HTTP request URI by using C#?

I want to send a HTTP request that looks like this:
http://api.com/main?id=1234&id=5678, the id will be GUID in string eventually.
I tried the below piece of code:
var idString = string.Join(",", listOfIds);
var queryString = new Dictionary<string, string>
{
{"id", idString}
};
requestUri = QueryHelpers.AddQueryString(requestUri, queryString);
This will give me like: http://api.com/main?id=1234,5678 but I want the style like above.
Is there anyway to achieve this without using for loop?
Thanks!
QueryHelpers doesn't work with arrays because there's no standard way to pass an array of values in a query string. Some applications accept id=1,2,3 others id=1&id=2&id=3 while others id[0]=1&id[1]=2&id[2]=3.
.NET (Core) 5 and later
AddQueryString now works with lists of KeyValuePair<string,string>or KeyValuePair<string,StringValues>
var parameters=new []{
new KeyValuePair("id",new StringValues(arrayOfIds)),
new KeyValuePair("other","value"),
...
};
var finalUri=QueryHelpers.AddQueryString(requestUri, parameters);
The StringValues constructors accept either a single string or an array of strings
Before .NET (Core) 5
String.Join itself uses a loop and a StringBuilder to create a new string without allocating temporary strings. Strings are immutable, so any string modification operation results in a new temporary string.
You could use the source code as a guide to build your own loop. A quick solution could be something like this:
string ArrayToQueryString_DONT_USE(string name,string[] values)
{
var result=new StringBuilder();
result.AppendFormat("{0}={1}",name,value);
for(int i=1;i<values.Length;i++)
{
result.AppendFormat("&{0}={1}',name,values[i]);
}
return result.ToString();
}
Unfortunately, that won't work if the parameter names or values need encoding. That's what AddQueryString does, using, once again, a StringBuilder to avoid allocating temporary strings. We can borrow that code as well:
string ArrayToQueryString(string name,string[] values)
{
var result=new StringBuilder();
result.AppendFormat("{0}={1}",name,value);
for(int i=1;i<values.Length;i++)
{
result.Append('&');
result.Append(UrlEncoder.Default.Encode(name));
result.Append('=');
result.Append(UrlEncoder.Default.Encode(values[i]));
}
return result.ToString();
}

Use Like in Linq query EF Core [duplicate]

This question already has answers here:
Like Operator in Entity Framework?
(9 answers)
Closed 3 years ago.
I have the below method in the EF Core application
public List<Prj_Detail> GetByOrg(string org)
{
var data = _context.Prj_Details.Where(w => w.Account_Name == org).ToList();
return data;
}
Here instead of == I need to check for Like how can I do that in my method
Like others have said you can do a Contains operator however in some cases this casues an unncessary TSQL casting. Instead you could use the in-built Entity Framework functions like so:
_context.Prj_Details.Where(EF.Functions.Like(w.Account_Name, org)).ToList();
Have you tried using Contains?
var data = _context.Prj_Details.Where(w => w.Account_Name.Contains(org)).ToList();
You can use StartsWith and EndsWith too.
Here's more information about it.
Could try with Contains to filter.
Please refer the below code.
depending on LeftRim/RightTrim/upperCase/LowerCase
public List<Prj_Detail> GetByOrg(string org)
{
var data = _context.Prj_Details.Where(w => w.Account_Name.Contains(org)).ToList();
return data;
}

How do i convert a JSON string to a native C# array using a namespace compatible with Windows Store Apps?

I am trying to make a windows 8 Store app that gets results from a MySQL database from a PHP page as a REST service.
I'm looking for the PHP to return a JSON representation of an array of strings and have done that happily when dong the same between Javascript and PHP.
I need to take that same JSON string and use it in my C# Windows 8 store App, is there a way to take the return of that PHP page and convert it into a normal C# array, not a dictionary or more complex collection.
The database does have four fields so if i have to use a special object made for this i will, but I'd rather I didn't as this function doesn't require that amount of data.
The PHP page is like so - $search_text is passed in via a GET:
$databaseConnection = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if ($databaseConnection->connect_error)
{
echo "Database connection failed: $databaseConnection->connect_error";
}
else
{
$search_text = $search_text."%";
$query = "SELECT DISTINCT street FROM gritroutes WHERE street LIKE ? LIMIT 5";
$statement = $databaseConnection->prepare($query);
$statement->bind_param('s', $search_text);
$statement->execute();
$statement->store_result();
$statement->bind_result($street);
$autonumber = 1;
while ($statement->fetch())
{
$resultarr[] = $street;
}
$statement->close();
echo json_encode($resultarr);
}
Just to be clear. I am writing a Windows Store App, the System.Web Namespace is unavailable so i can't use JavaScriptSerializer.
Just to add to Matthew's answer, you can deserialize using Json.NET (you can get it from NuGet), you'd do something like:
List<string> myStrings = JsonConvert.DeserializeObject<List<string>>(myJson);
This is in:
using Newtonsoft.Json;
Check out this article for practical example.
EDIT
- I'd also like to throw in this link, since it's just awesome.
I hope this helps.
Take a look at the JavaScriptSerializer class.
string myJson = "{blablabla I'm json}";
var serializer = new JavaScriptSerializer();
var myStrings = serializer.Deserialize<List<string>>(myJson);
foreach (var str in myString)
{
Console.WriteLine(str);
}
You could also use native Windows.Data.Json classes to do the parsing:
string json = #"[""item1"", ""item2"", ""item3""]";
var array = JsonArray.Parse(json).Select(i => i.GetString()).ToArray();

Slicing a FormCollection by keys that start with a certain string

Is there a nice linqy way of splitting a FormCollection into a Dictionary<string,string> that contains only those keys that start with a certain string?
(This question is basically the same as this-> but for C#/FormCollection instead of python Slicing a dictionary by keys that start with a certain string)
Here's what I came up with to get around the problem:
public ActionResult Save(FormCollection formCollection) {
var appSettings = new Dictionary<string, string>();
var appKeys = formCollection.AllKeys.Where(k => k.StartsWith("AppSettings."));
foreach (var key in appKeys)
{
appSettings[key] = formCollection[key];
}
...
Edit: The problem with this code, is that I have to do it multiple times for different StartsWith strings, and will therefore need to create a 'utility' method to do the above.
It would be nice if it could read in one line like:
formCollection.Where(k=>k.Key.StartsWith("AppSettings.");
Background (not necessary to solve the problem): The context is asp.net mvc, and of a form with a dynamic dictionary of fields.
It's also similar to this question - Return FormCollection items with Prefix - but not quite the same.
And having read this answer How to build C# object from a FormCollection with complex keys - I started to wonder whether I'd be better off not even using form post, but sending JSON instead.
If you're looking for a "nice" way of taking an existing dictionary, producing a new dictionary with copies of keys+values, for a subset of the keys, some LINQ code will do this nicely:
var appSettings = formCollection.AllKeys
.Where(k => k.StartsWith("AppSettings."))
.ToDictionary(k => k, k => formCollection[k]);
[HttpPost]
public ActionResult Index(FormCollection collection)
{
Dictionary<string,object> form = new Dictionary<string, object>();
collection.CopyTo(form);
return View();
}

Is converting a NameValueCollection to a querystring using a c# lambda efficient?

In researching how to convert a NameValueCollection to a querystring, I have come across different methods. I am curious if the shorter lambda syntax is as efficient as it could be.
How to convert NameValueCollection to a (Query) String using a iterating function.
public static String ConstructQueryString(NameValueCollection parameters)
{
List<String> items = new List<String>();
foreach (String name in parameters)
items.Add(String.Concat(name, "=", System.Web.HttpUtility.UrlEncode(parameters[name])));
return String.Join("&", items.ToArray());
}
Join a NameValueCollection into a querystring in C# uses a lambda expression, which looks nice but I'm not sure if it is efficient code.
private static string JoinNvcToQs(NameValueCollection qs)
{
return string.Join("&", Array.ConvertAll(qs.AllKeys, key => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(qs[key]))));
}
I would do it like this:
public static string ConstructQueryString(NameValueCollection parameters)
{
var sb = new StringBuilder();
foreach (String name in parameters)
sb.Append(String.Concat(name, "=", System.Web.HttpUtility.UrlEncode(parameters[name]), "&"));
if (sb.Length > 0)
return sb.ToString(0, sb.Length - 1);
return String.Empty;
}
This way you create less objects (that have to be cleaned up by the garbage collector)
First of all, the best thing you can do is test and see if the performance is acceptable for your application, we can tell you generalities about performance but in the end it comes down to your needs and only you know the answers to that.
As to the question at hand, any time you use a delegate (which is what a lambda creates) rather than executing the code directly you'll take a performance hit. In most cases the hit is acceptable but if this code needs the absolute best possible performance (say it's in an inner loop) then you need to go with your first method.
That said, if you're creating a querystring, presumably you're about to hit the database which will likely take considerably longer than either method of creating the querystring in the first place.
NameValueCollection's ToString method will build the query string for you. I haven't done any benchmarking, but I'd imagine the implementation would be more efficient than something using lambdas or foreach.
(The ToString solution doesn't seem to be well-documented; I only found it because this answer used it in a code sample.)

Categories