Is there a straightforward way of converting:
string str = "a=1,b=2,c=3";
into:
dynamic d = new { a = 1, b = 2, c = 3 };
I think I could probably write a function that splits the string and loops the results to create the dynamic object. I was just wondering if there was a more elegant way of doing this.
I think if you convert the "=" into ":" and wrap everything with curly brackets you'll get a valid JSON string.
You can then use JSON.NET to deserialize it into a dynamic object:
dynamic d = JsonConvert.DeserializeObject<dynamic>(jsonString);
You'll get what you want.
You may use Microsoft Roslyn (here's the all-in-one NuGet package):
class Program
{
static void Main(string[] args)
{
string str = "a=1,b=2,c=3,d=\"4=four\"";
string script = String.Format("new {{ {0} }}",str);
var engine = new ScriptEngine();
dynamic d = engine.CreateSession().Execute(script);
}
}
And if you want to add even more complex types:
string str = "a=1,b=2,c=3,d=\"4=four\",e=Guid.NewGuid()";
...
engine.AddReference(typeof(System.Guid).Assembly);
engine.ImportNamespace("System");
...
dynamic d = engine.CreateSession().Execute(script);
Based on the question in your comment, there are code injection vulnerabilities. Add the System reference and namespace as shown right above, then replace the str with:
string str =
#" a=1, oops = (new Func<int>(() => {
Console.WriteLine(
""Security incident!!! User {0}\\{1} exposed "",
Environment.UserDomainName,
Environment.UserName);
return 1;
})).Invoke() ";
The question you described is something like deserialization, that is, contructing objects from data form(like string, byte array, stream, etc). Hope this link helps: http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx
Here's a solution using ExpandoObject to store it after parsing it yourself. Right now it adds all values as strings, but you could add some parsing to try to turn it into a double, int, or long (you'd probably want to try it in that order).
static dynamic Parse(string str)
{
IDictionary<String, Object> obj = new ExpandoObject();
foreach (var assignment in str.Split(','))
{
var sections = assignment.Split('=');
obj.Add(sections[0], sections[1]);
}
return obj;
}
Use it like:
dynamic d = Parse("a=1,b=2,c=3");
// d.a is "1"
Related
Here is the list array:
{"things":{"1":"1_4","3":"3_13","4":"4_18","5":"5_25","6":"6_28","7":"7_32"}}
here is the code:
var t = things;
string aa = t[0].ToString();
How do I split the above array in , separator and _ .
from the above array i want only 1_4,3_13...this column and save in two different var.
when I am using
string[] ss = aa.Split(new char[] { ',', '|', }, System.StringSplitOptions.RemoveEmptyEntries);
the problem is that in first list {"things":{"1":"1_4".
comes
so how to remove {"things"??
You should not parse JSON yourself. Do not reinvent the wheel.
You should define a class
public class MyClass
{
[JsonProperty("things")]
public Dictionary<int, string> Things { get; set; }
}
Then deserialize your string into an instance of MyClass
var rawData = "{\"things\":{\"1\":\"1_4\",\"3\":\"3_13\",\"4\":\"4_18\",\"5\":\"5_25\",\"6\":\"6_28\",\"7\":\"7_32\"}}";
var data = JsonConvert.DeserializeObject<MyClass>(rawData);
Then you can use data
Console.WriteLine(data.Things[1]);
You should add Newtonsoft.Json Nuget package to your project and add using Newtonsoft.Json namespace to your code file.
Instead of string manipulation, you should use JSON library like Json.Net. Simply, because you are working with string in JSON format and it will be easier to work with that information if you deserialize it into proper object or JObject.
Example with JObject:
string json = #"{""things"":{""1"":""1_4"",""3"":""3_13"",""4"":""4_18"",""5"":""5_25"",""6"":""6_28"",""7"":""7_32""}}";
var jObj = Newtonsoft.Json.Linq.JObject.Parse(json);
var prop1 = jObj.GetValue("things").GetPropertyValue("1").ConvertTo<string>();
var prop4 = jObj.GetValue("things").GetPropertyValue("4").ConvertTo<string>();
Note: You can create classes which will represent your JSON structure, if you want to have strongly typed object structure.
You should first split by { then discard the first and after that you are left with:
"1":"1_4","3":"3_13","4":"4_18","5":"5_25","6":"6_28","7":"7_32"}}
Now you split with , and get
"1":"1_4"
"3":"3_13" and so on.
Then you split each with : and take the second one.
Only remember that the last one is "7_32"}} which you should remove the trailing }}
Like this:
var elems = aa.Split(new[] { '{' })[1].Split(new[] { ',' });
var res = elems.Select(obj => obj.Trim("}".ToCharArray()).Split(new[] { ':' }));
Hope this is what you want :)
given an apparently invalid json
(which comes from google)
https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=de&dt=t&q=Science
of
[[["Wissenschaft","Science",,,2]],,"en"]
i want to get the values of Wissenschaft and Science
if figured out a very inelegant way to do it with Json.net via
string h = "[[[\"Wissenschaft\",\"Science\",,,2]],,\"en\"] ";
var obj = JsonConvert.DeserializeObject<List<dynamic>>(h);
JArray arr1 = obj[0];
var arr2 = arr1.First;
var x = arr2.First.Next;
string s = x.ToString();
is there some better, less verbose way ?
Here is a more concise version, maybe somebody has one which also retains
the other values from the top array
string h = "[[[\"Wissenschaft\",\"Science\",,,2]],,\"en\"]";
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Error = (serializer, err) =>
{
err.ErrorContext.Handled = true;
//ignore all errors
};
var obj = JsonConvert.DeserializeObject<List<List<List<dynamic>>>>(h,settings);
string strWissenschaft = obj[0][0][0];
string strScience = obj[0][0][1];
As you see i only care for the values in the most nested array, the other values are lost.
For first this is not valid JSON object but nevermind as you said Json.NET will parse it by adding null values into empty commas.
Because this is not valid object and it is just an array in some JSON format. There will probably no better way then parse it into dynamic List as you already did.
In case of { } at start and end and some keys:values format you can deserialize it into C# object according to class which you can define.
For example there is a
string str = "[2,3,4,5]"
How to convert this array of type string into a list where I can get each element in the list of type ushort?
The string gets the value "[2,3,4,5]" from ruby script.
Using linq you could do it like
var numbers = str.Where(y=>Char.IsDigit(y)).Select(p=>UInt16.Parse(p.ToString())).ToArray();
It's actually quite simple. All you need to do is write a method that parses the string and splits it up. Here is an basic example with NO error checking or optimizations. The naming convention is purely for your understanding purposes.
List <ushort> ConvertToUShortList (string arrayText)
{
var result = new List<ushort> ();
var bracketsRemoved = arrayText.Replace ("[", "").Replace ("]", "");
var numbersSplit = bracketsRemoved.Split ( new string[] {","}, System.StringSplitOptions.None);
foreach (var number in numbersSplit)
{
result.Add (ushort.Parse (number));
}
return result;
}
I shouldn't need to explain anything in this method due to the names I have given things. If you don't understand anything, let me know and I'll clarify it for you.
Another method (more checks):
class Program
{
static void Main(string[] args)
{
var str = "[1,2,3,4,5,6,7,8,9]";
var x = FromRubyArray(str);
Console.WriteLine(str);
Console.WriteLine(string.Join("-", x));
Console.ReadLine();
}
public static List<ushort> FromRubyArray(string stra)
{
if (string.IsNullOrWhiteSpace(stra)) return new List<ushort>();
stra = stra.Trim();
stra = stra.Trim('[', ']');
return stra
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => Convert.ToUInt16(s))
.ToList();
}
}
Since this string is using a "Json-like" format, you can use this code:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var array = serializer.Deserialize<ushort[]>("[2,3,4,5]");
You just need to reference the System.Web.Extensions assembly
Another elegant way using Newtonsoft's Json.net (http://www.newtonsoft.com/json)
var ushortArray = JsonConvert.DeserializeObject<List<ushort>>(myString);
You could do something like
List<ushort> myUshorts = new List<ushort>("[200,3,4,5]".Trim('[', ']').Split(',').Select(ushort.Parse));
if you know that's exactly how the output will be.
i have a controller where i read a html file into a variable.
After read it i replace some values from the variable to other values,
but the problem is that nothing happend.
What is wrong here ?
can someone give me a hand with this?
string path = "/mypath/myfile.html";
string s = System.IO.File.ReadAllText(path);
s.Replace("#%a%#","hi");
s.Replace("#%b%#","yo");
s.Replace("#%c%#","asdfasdf");
s.Replace("#%d%#", "http://www.google.com");
Strings are immutable - you should assign result of replacement to your string. Also you can chain replacement operations like this:
string s = System.IO.File.ReadAllText(path)
.Replace("#%a%#","hi")
.Replace("#%b%#","yo")
.Replace("#%c%#","asdfasdf")
.Replace("#%d%#", "http://www.google.com");
Just keep in mind - all string operations (like Replace, Substring etc) will create and return new string, instead of changing original. Same implies to operations on DateTime and other immutable objects.
UPDATE: You can also declare dictionary of your replacements and update string in a loop:
var replacements = new Dictionary<string, string> {
{ "#%a%#","hi" }, { "#%b%#","yo" }, { "#%c%#","asdfasdf" } // ...
};
string s = System.IO.File.ReadAllText(path);
foreach(var replacement in replacements)
s = s.Replace(replacement.Key, repalcement.Value);
A string is immutable. Basically, an object is immutable if its state doesn’t change once the object has been created. Consequently, a class is immutable if its instances are immutable.
string path = "/mypath/myfile.html";
string s = System.IO.File.ReadAllText(path);
s = s.Replace("#%a%#","hi");
s = s.Replace("#%b%#","yo");
s = s.Replace("#%c%#","asdfasdf");
s = s.Replace("#%d%#", "http://www.google.com");
I have a string in my C# model populated with this string:
"[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]"
Is there a way, using LINQ or RegEx, that I could parse out the partner_id's - so I ended up with a list object with:
229547
id34234
Thanks for your help, Mark
I have never used any JSON parser but if it comes to Regex you could try something like this:
private static void regexString()
{
string myString = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";
string[] stringList = Regex.Split(myString, "},{");
for (int i=0; i<stringList.Length ;i++)
{
stringList[i] = Regex.Split(Regex.Split(stringList[i], "partner_id\\\":\\\"")[1], "\\\",\\\"partner_url\\\"")[0];
}
}
Also there is a nice website to help you with creating your own regex patterns in the future, check it out:
gskinner.com
And a nice and short tutorial:
www.codeproject.com
Assuming your link having partner id always-
string Name = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";
string[] splittedString = Regex.Split(Name, "}");
List<string> allIds = new List<string>();
foreach (var i in splittedString)
{
var ids =Regex.Split(i, "/");
string id = ids[ids.Length - 1];
allIds.Add(id);
}
If that is the general format of the string then this regex should work
(?i)(?<=(partner_id).{5})\w+
Test here
This from your string will get
229547 and id34234
(?i) = Case insesitivity
(?<=(partner_id).{5}) = postive lookbehind for parter_id then any 5 characters which in this case will be \":\"
\w+ = Any alphanumeric characters one or more times
Hope this helped
Since this is JSON, you probably shouldn't bother trying to get a regex working. Instead, you can parse the JSON and then use LINQ.
using System.Web.Script.Serialization; // (in System.Web.Extensions.dll)
...
string s = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";
JavaScriptSerializer j = new JavaScriptSerializer();
object[] objects = (object[])j.DeserializeObject(s);
string[] ids = objects.Cast<Dictionary<string, object>>()
.Select(dict => (string)dict["partner_id"])
.ToArray();
It's a little messy to deserialize it to an object, because you don't have any type information. If you're not afraid of making a small class to deserialize into, you can do something like this:
class Foo
{
public string partner_id
{
get;
set;
}
}
...
JavaScriptSerializer j = new JavaScriptSerializer();
string[] ids = j.Deserialize<Foo[]>(s).Select(x => x.partner_id).ToArray();
Note that there are other options for deserializing JSON. I simply chose the most general-purpose one that's built in.