using strings in c#.net - c#

Hi How do I retrieve the number from the following string,
{"number":100,"data":[test]}
The number could be of any length.
I used the following code. but it gives and error message
strValue.Substring((strValue.IndexOf(":")+1), (strValue.IndexOf("data")));
the output comes like
100,"data":[
Thanks,

It looks like your input string is JSON. Is it? If so, you should use a proper JSON parser library like JSON.NET

As noted by Jon, your input string seems to be a JSON string which needs to be deserialized. You can write your own deserializer, or use an existing library, such as Json.NET. Here is an example:
string json = #"[
{
""Name"": ""Product 1"",
""ExpiryDate"": ""\/Date(978048000000)\/"",
""Price"": 99.95,
""Sizes"": null
},
{
""Name"": ""Product 2"",
""ExpiryDate"": ""\/Date(1248998400000)\/"",
""Price"": 12.50,
""Sizes"": null
}
]";
List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);

Your attempt is close. There are two (possibly three issues) I found.
Your string has a comma after the number you're looking for. Since your code is searching for the index of "data", your end index will end up one character too far.
The second paramter of String.Substring(int, int) is actually a length, not an end index.
Strings are immutable in C#. Because of this, none of the member functions on a string actually modify its value. Instead, they return a new value. I don't know if your code example is complete, so you may be assigning the return value of SubString to something, but if you're not, the end result is that strValue remains unchanged.
Overall, the result of your current call to string.Substring is returning 100,"data":[tes. (and as far as I can see, it's not storing the result).
Try the following code:
string justTheNumber = null;
// Make sure we get the correct ':'
int startIndex = strValue.IndexOf("\"number\":") + 9;
// Search for the ',' that comes after "number":
int endIndex = strValue.IndexOf(',', startIndex);
int length = endIndex - startIndex;
// Note, we could potentially get an ArguementOutOfRangeException here.
// You'll want to handle cases where startPosition < 0 or length < 0.
string justTheNumber = strValue.Substring(startIndex, length);
Note: This solution does not handle if "number": is the last entry in the list inside your string, but it should handle every other placement in it.
If your strings get more complex, you could try using Regular Expressions to perform your searches.

Parsing JSON spring in that way is very bad practice as everything is hardcoded. Have you though of using 3rd party library for parsing JSON strings, like Newtonsoft JSON.

I guess you needed to use IndexOf(",") istead of IndexOf("data")

Related

C# How to turn String with Carriage Return symbols in to an array

I am calling some external method that returns a string like this.
"[\r\n \"0\",\r\n \"1\",\r\n \"2\"\r\n]"
How do I turn this in to an Array with the values 1,2,3 ?
Should I be trying to split/substring methods to do this, or is there some kind of built in .net method that can do this?
I have tried,
string theStringResult = Class.ExternalMethod();
theStringResult.ToArray()
The returned string appears to be a JSON array made up of strings.
The line breaks are part of a pretty print version of the JSON string which, when not escaped, would look like this...
[
"0",
"1",
"2"
]
You can use Newtonsoft's Json.Net to parse and deserialize the returned string into a strongly typed object.
string theStringResult = Class.ExternalMethod();
string[] array = JsonConver.DeserializeObject<string[]>(theStringResult);
The above should produce the desired result
Try this.
string Originalstring = "[\r\n \"0\",\r\n \"1\",\r\n \"2\"\r\n]";
string[] result = Originalstring.Split(new String[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
This should split a string that has a carriage return into an array and remove any empty entries
The method you're looking for is String.Split. It takes a single character as a parameter and returns an array of pieces split wherever that character is found.
In your case you have two characters ("\r\n") so either you split and post-process the array, or you replace the pair with a single character and then split.
In code it looks like this:
string source = "\r\n0\r\n1\r\n2\r\n";
string parts = source.Replace("\r\n", "\n").Split('\n');
The resultant array is ["0", "1", "2"].
Oh, that's a literal JSON string... that wasn't entirely clear on first viewing.
If the array is fairly consistent you could do string manipulation, but it's not ideal.
Add the NewtonSoft.Json NuGet package to your project and use the following:
string source = "[\r\n \"0\",\r\n \"1\",\r\n \"2\"\r\n]";
string[] parts = Newtonsoft.Json.JsonConvert.DeserializeObject<string[]>(source);
Same output as above.

Smartly replace strings

I am working with JSON API. As c# doesn't accept characters like - (minus) or . (point), I had to replace each character by _ (underscore). The replacement happens when the JSON response is received as a string so that every attribute name containing a - or a . will have it replaced by a _ , then every attribute name will be the same as the attributes names in the class it will be deserialized into.
To make it clearer, here are some examples:
I recieve the following JSON : { "id": 1, "result": [ { "data": [ { "adm-pass": ""}]}
In the class I want to deserialize into I have this attribute : public String adm_pass {get; set;}
So I replace the minus with an underscore so that the NewtonSoft parser can deserialize it accordingly.
My problem is that I sometimes I get some negative integers in my JSON. So if I do the string replacement in: {"beta" : -1}, I get a parsing exception since the -1 (integer here) becomes _1 and cannot be deserialized properly and raises an exception.
Is there a way to replace the string smartly so I can avoid this error?
For example if - is followed by an int it's not replaced.
If this way does not exist, is there a solution for this kind of problems?
Newtonsoft allows you to specify the exact name of the JSON property, which it will use to serialize/deserialize.
So you should be able to do this
[JsonProperty("adm-pass")]
public String adm_pass { get; set; }
This way you are not restricted to name your properties exactly as the JSON property names. And in your case, you won't need to do a string replace.
Hope this helps.
You'll have to check that you are replacing the key and not the value, maybe by using a regex like http://regexr.com/3d471
Regex could work as wlalele suggests.
But I would create a new object like this:
Create a new object:
var sharpObj = {};
loop through the objects as properties as described here:
Iterate through object properties
for (var property in object) {
if (object.hasOwnProperty(property)) {
// do stuff
}
}
In the // do stuff section, create a property on sharpObj with the desired string replacements and set the property to the same value.
var cleanProperty = cleanPropertyName(property);
sharpObj[cleanProperty] = orginalObject[property];
Note: I assume you can figure out the cleanPropertyName() method or similar.
Stringify the object
var string = JSON.stringify(sharpObj);
You can substring to check whether the next character is an integer, this can adapt into your code easily as you already find a character, as such you could do
int a;
if(int.TryParse(adm_pass.Substring(adm_pass.IndexOf("-") + 1,1),out a))
{
//Code if next character is an int
}
else
{
adm_pass = adm_pass.Replace("-","_");
}
This kind of code can be looped until there are no remaining hyphens/minuses

Deserialize JSON array into string array

Say I have a string representing an array of objects in JSON form:
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
What I want is an array of strings, each string being the string representation of a JSON object - NOT the object itself. It should look something like this:
string[] s = new string[]
{
"{\"name\":\"Person1\"}",
"{\"name\":\"Person2\"}"
};
1) Almost every search I attempt pulls up millions of results on how to simply deserialize a JSON string using (eg) Json.NET. This is not what I want to do.
2) I have tried building a class representing the objects to temporarily loop through a deserialize/serialize mapping each to a string in an array, but the schema for the objects is variable (hence why I only need a string representation).
3) I have attempted a few regex to try and do this, but my JSON string can contain fields that contain JSON strings as their value (icky, but out of my control) and so nested character escaping etc drove me partially mad before I decided to beg for help here.
Surely this should be simple? Anybody got any pointers?
You'll need to deserialize it, and then serialize each object independently.
For example (using Newtonsoft.Json):
string json = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
var objects = JsonConvert.DeserializeObject<List<object>>(json);
var result = objects.Select(obj => JsonConvert.SerializeObject(obj)).ToArray();
Yields (as a string[]):
{"name":"Person1"}
{"name":"Person2"}
If you try to avoid deserializing and serializing, you're almost certain to run into an edge case that will break your code.
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
var Json = JsonConvert.DeserializeObject<List<object>>(s);
string[] Jsonn = Json.Select(x => x.ToString()).ToArray();
[] Jsonn returns string array instead of object array with JObject formatted.
Hope this one help you.
Why don't you just use this
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
string[] t = s.Split(',');
I tried it. It simply gives you string array as you want it....

How to place double quotes inside the double quotes of string.IndexOf() function?

I have a String I want to get the index of the "id:" i.e the id along with the double quotes.
How I am supposed to do so inside C# string.IndexOf function?
This will get the index of the string you want:
var idx = input.IndexOf("\"id:\"");
if you wanted to pull it out you'd do something like this maybe:
var idx = input.IndexOf("\"id:\"");
var val = input.Substring(idx, len);
where len is either a statically known length or also calculated by another IndexOf statement.
Honestly, this could also be done with a Regex, and if an example were available a Regex may be the right approach because you're presumably trying to get the actual value here and it's presumably JSON you're reading.
" is an escape sequence
If you want to use a double quotation mark in your string, you should use \" instead.
For example;
int index = yourstring.IndexOf("\"id:\"");
Remember, String.IndexOf method gets zero-based index of the first occurrence of the your string.
This is a simple approach: If you know double quote is before the Id then take index of id - 1?
string myString = #"String with ""id:"" in it";
var indexOfId = myString.IndexOf("id:") - 1;
Console.WriteLine(#"Index of ""id:"" is {0}", indexOfId);
Reading between the lines, if this is a JSON string, and you have .NET 4 or higher available, you can ask .NET to deserialize the string for you rather than parsing by hand: see this answer.
Alternatively you might consider Json.NET if you're working very heavily with JSON.
Otherwise, as others note, you need to escape the quotes, so for example:
text.IndexOf("\"id:\"")
text.IndexOf(#"""id:""")
or for overengineered legiblity:
string Quoted(string text)
{
return "\"" + text + "\""; // generates unnecessary garbage
}
text.IndexOf(Quoted("id:"))

Get XML from a string

I have a Socket communication in my Windows Phone app, but when I call it I can sometimes get a result, that looks like this
\0\0\0\0<RESULT><DATA>...</DATA></RESULT>\0
I want to remove the start and the end of it so I only get the XML, but what is the best way to do it?
I have thought about Regex, but I can not make it work :(
It sounds like a problem with your protocol, but to remove the \0 characters you could do a simple trimming of the string.
If your string has the actual \ and 0 characters in it then you could do the following:
var fixedData = receivedData.Trim(new[] { '\\', '0' });
And if the string starts with null characters (encoded as \0) then you could to:
var fixedData = receivedData.Trim(new[] { '\0' });
Both examples assume that the variable receviedData is a String containing your data.
I have not enough information to answer you correctly, so I will suggest the following :
You should try to map the data you are receiving from your socket to a serializable class.
And then you serialize the classObject to an XML document.
public class socketDataToMap
{
public string Data {get; set;}
}
and then
var ser = new XmlSerializer(typeof(socketDataToMap));
using (var reader = XmlReader.Create(yourSocketStream))
{
var deserializedObject = ser.Deserialize(reader) as socketDataToMap;
}
and then you serialize to an XML file. I see something like this for your problem.
If your result have to be XML and more characters(else \0) can be in start or end of your string, these code can be useful:
var start = inputString.IndexOf('<');
var end = inputString.LastIndexOf('>');
var result = inputString.Substring(start, end - start);
String.IndexOf Method (Char): Reports the zero-based index of the first occurrence of the specified Unicode character in this string.
String.LastIndexOf Method (Char): Reports the zero-based index position of the last occurrence of a specified Unicode character within this instance.
String.Substring Method (Int32, Int32): Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.

Categories

Resources