Convert unformatted string (not valid json) to json - c#

I have a string which I get from a webservice which looks like this:
({
id=1;
name="myName";
position="5";
})
which is not a parsable json. I wanted to ask if there are any ways besides going character to character and correcting them to convert such string into a parsable json like this:
{
"id":1,
"name":"myName",
"position":"5"
}

Check this link it will be helpful :
https://forum.unity3d.com/threads/json-web-services.366073/

You cold run a bunch of regex replaces for each change. But you'll need captures for the property names etc The performance will be horrible.
If the format is known and reliable (eg what happens with collections/arrays and sub-objects). And the service provider does not provide a client or SDK. Then your best bet is to write your own parser. It's not that hard to create your own from scratch. Or you can use a parser library like Irony.net or eto.parse. Both of these allow you to construct a grammar in c# so it is fully self contained without the need for compiler-compilers and generated code. There is also a class of parser called "monadic" parsers like Sprache which are of a simpler nature (once you wrap your head around them).
Whichever approach is taken you'll end up with a way of recognising each property and object boundary where you can do what you need to do: set a property; create a JToken; whatever...
Then you can wrap the whole lot in a MediaTypeFormatter and call the service via HttpClient and get objects out.

Finally I had to write my own function to convert it to a parsable json, here's the function I wrote:
public string convertToJson(string mJson)
{
mJson = mJson.Replace("(","[");
mJson = mJson.Replace(")","]");
string mJson2 = mJson.Trim('[',']');
string[] modules = mJson2.Split(',');
for(int i = 0;i<modules.Length;i++)
{
Debug.Log("module["+i+"]: " + modules[i]);
}
for(int m=0;m<modules.Length;m++)
{
char[] mCharacter = {'{','}'};
modules[m] = modules[m].Replace("{",string.Empty).Replace("}",string.Empty).Trim();
Debug.Log("module["+m+"] after trim: " + modules[m]);
string[] items = modules[m].TrimEnd(';').Split(';');
modules[m] = "{";
for(int j=0;j<items.Length;j++)
{
Debug.Log("item["+j+"]: " + items[j]);
string[] keyValue = items[j].Split('=');
Debug.Log("key,value: " + keyValue[0] + ", " + keyValue[1]);
modules[m] = modules[m] + "\"" + keyValue[0].Trim() + "\":" + keyValue[1].Trim() + ",";
}
modules[m] = modules[m].Substring(0,modules[m].Length-1) + "}";
Debug.Log("modules["+m+"] final: " + modules[m]);
}
string finalJson = "[";
for(int m=0;m<modules.Length;m++)
{
finalJson = finalJson + modules[m] + ",";
}
finalJson = finalJson.Substring(0,finalJson.Length-1) + "]";
Debug.Log("finalJson: " + finalJson);
return finalJson;
}

Related

C# - Add a whitespace between two strings

I have code to display a vehicle by its Make and Model.
productName.Text = p.Make + p.Model
The above code displays the text as such: "BentleyContinental", how can I make the text display as such "Bentley Continental".
You can use string.Format():
productName.Text = string.Format("{0} {1}", p.Make, p.Model);
Or you can use string interpolation (if you are on C# 6 or higher):
productName.Text = $"{p.Make} {p.Model}";
Or you can do just as you have (string concatenation) but add in a space:
productName.Text = p.Make + " " + p.Model;
Use the string.concat method to concatenate string parts.
productName.Text = string.concat(p.Make, " ", p.Model);
In general, you use the string.concat when you know you'll add less than a dozen parts. More than that, or if you are in a loop, there is more benefits using the StringBuilder class.
productName.Text = p.Make + " " + p.Model
Just concatenate a space between two words. I think this is the easiest way.

Escaping and double quotes together with Linq

I am making a small piece of code where I look for all nodes in XML containing "folder name=\"u"" .
I have problems with the string literals, I tried with # and escape or double quotes without any success. Here is the code :
public class Folders
{
public static IEnumerable<string> FolderNames(string xml, char startingLetter)
{
string[] MyString;
List<string> MyList = new List<string>();
string item = "";
StringSplitOptions.None)).ToList();
MyString = xml.Split('>') ;
var matchingvalues = MyString
.Where(stringToCheck => stringToCheck.Contains("<folder name=\\\""));
return matchingvalues;
}
public static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<folder name=\"c\">" +
"<folder name=\"program files\">" +
"<folder name=\"uninstall information\" />" +
"</folder>" +
"<folder name=\"users\" />" +
"</folder>";
foreach (string name in Folders.FolderNames(xml, 'u'))
Console.WriteLine(name);
Console.ReadLine();
}
How should I write
var matchingvalues = MyString.Where(stringToCheck => stringToCheck.Contains("
?
You're not even using your startingLetter parameter in FolderNames
You say you're looking for "folder name=\"u"", but your code looks for "<"folder name=\\\"". Disregarding the missing "u", you're looking for a literal backslash as well. Which doesn't exist in your xml. The backslashes in your xml are for escaping the quotes.
You haven't posted your real code because your method doesn't even work. WTF is this??
StringSplitOptions.None)).ToList();
You don't use the item variable.
Hopefully the above is enough to show where you went wrong. Better still, use .NET's xml parsing abilities to get the values. Currently your method lies; it doesn't just return "Folder Names", it returns a mess of half-xml as well.
The main problem isn't really with the escaping.
But with the fact you reinvented the wheel a little bit.
There are multiple xml parsers in c#.
Linq to xml is one of them. with it you could write something simple like:
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<folder name=\"c\">" +
"<folder name=\"program files\">" +
"<folder name=\"uninstall information\" />" +
"</folder>" +
"<folder name=\"users\" />" +
"</folder>";
XElement xElement = XElement.Parse(xml);
IEnumerable<string> values = xElement.
Descendants("folder").
Where(element => element.Attribute("name")?.Value?.StartsWith("u") == true).
Select(element => element.Attribute("name").Value);

How do i build a string array out of a list

i have a function that returns a List of strings
static List<string> getPushIDsForCategory(string user, string project)
{
....
}
and im then using that function to build a json string on the fly
var JSON = "{\"app_id\": \"MY_ID_KEY\"," +
"\"contents\": {\"en\": \"My Message\"}," +
"\"ios_badgeType\": \"Increase\"," +
"\"ios_badgeCount\": \"1\"," +
"\"include_player_ids\": [\"" + getPushIDsForCategory(user, project) + "\"]" + //<-- that string array goes here (item 1, item 2, item 3, etc...)
"}";
when i run this code i get
{
...
"include_player_ids": ["System.Collections.Generic.List 1[System.String]"]
...
}
if I replace it with getPushIDsForCategory(user, project)).ToArray
i get
{
...
"include_player_ids": ["System.String[]"]
...
}
how can i get acutal strings and not object types?
I believe what you are looking for is string.Join(", ", getPushIDsForCategory(user, project));
This will take each object in your array and join them together with the delimiter of ", " (comma space)
as others of mentioned, this WILL cause headache later down the line.
take a look at http://www.newtonsoft.com/json
Changes:
static string[] getPushIDsForCategory(string user, string project)
var idsArray = String.Join(", ", getPushIDsForCategory(user, project));
"\"include_player_ids\": [\"" + idsArray + "\"]"
That said, you might not want to create the Json like that. What you are building there is called "a magic string". This means that if there is a problem with yout Json, you will find out at runtime rather than compile time. Rather, have a class to which you map all the data and use that to create the Json.

Newline char in exchange appointments

I need to put an adress into a appointment. The address is constructed out of several variables. Of course I also need some newlines. But "\n" doesnt result in an new line when i open the appointment in outlook.
Ok here is code snippet:
string address = name + "\n" + strasse + "\n" + plz.ToString() + " " + ort;
if ( telefon != "") {
address = address + "\nTelefon:: " + telefon;
}
if ( natel != "") {
address = address + "\nNatel: " + natel;
}
if ( mail != "") {
address = address + "\nE-Mail: " +mail;
}
Nothing special. The Problem is when i write this to the body of an appointment, then there aren't any actual newlines.
Its pretty hard to diagnose this without seeing at least an example of the string you are passing, but one thing that I tend to do in my C# code is to use the constant:
Environment.NewLine
Or I use the StringBuilder class with the AppendLine() call to add a newline.
Edit: Based on your code snippet, I would write it this way (it will be more performant as well). With your snippet, lots of strings are being allocated (because strings are immutable). The recommended approach in this case is to use StringBuilder.
StringBuilder address = new StringBuilder();
address.AppendLine(name);
address.AppendLine(strasse);
address.Append(plz.ToString()); // This may not be neccessary depending on the type of plz, StringBuilder has overloads that will convert base types to string for you
address.Append(" ");
address.Append(ort);
if (!string.IsNullOrEmpty(telefon))
{
address.AppendLine();
address.Append("Telefon:: ");
address.Append(telefon);
}
if (!string.IsNullOfEmpty(natel))
{
address.AppendLine();
address.Append("Natel: ");
address.Append(natel);
}
if (!string.IsNullOrEmpty(mail))
{
address.AppendLine();
address.Append("E-Mail: ");
address.Append(mail);
}
return address.ToString();
Note: If you are using .Net 4.0 you can use string.IsNullOrWhitespace instead of IsNullOrEmpty to check for not just an empty string, but one that contains only whitespace.
Edit 2 - Based on your answer of needing <br /> tags instead of newlines.
const string newLine = " <br /> ";
StringBuilder address = new StringBuilder();
address.Append(name);
address.Append(newLine);
address.Append(strasse);
address.Append(newLine);
address.Append(plz.ToString()); // This may not be neccessary depending on the type of plz, StringBuilder has overloads that will convert base types to string for you
address.Append(" ");
address.Append(ort);
if (!string.IsNullOrEmpty(telefon))
{
address.Append(newLine);
address.Append("Telefon:: ");
address.Append(telefon);
}
if (!string.IsNullOfEmpty(natel))
{
address.Append(newLine);
address.Append("Natel: ");
address.Append(natel);
}
if (!string.IsNullOrEmpty(mail))
{
address.Append(newLine);
address.Append("E-Mail: ");
address.Append(mail);
}
return address.ToString();
Ok i got it now. I found out that appointments are stored in html format.
So i tried to use the html entity for \r\n, .That didn't work. I finally solved the problem by using the br tag
While you're absolutely correct about using <br/>, newline is not the only thing Exchange eats in notes/appointment body.
I ended up with the following code:
Regex NewlineRegex = new Regex("(\r\n)|(\r)|(\n)");
string valueToWrite = NewlineRegex.Replace(
SecurityElement.Escape(fieldValue), "<br/>")
.Replace(" ", " ")
.Replace("&apos;", "'"); // &apos; is not in HTML.
And even after that you will read back an extra "\r\n" in the end of the body/notes, so I have to .TrimEnd() them after reading.
you should try "\r\n"
See http://www.infinitec.de/post/2009/08/25/Exchange-WebServices-Bug-with-Lineendings.aspx

Regular expression to split string into equal length chunks

I have a string which would be delivered to my application in the format below:
ece4241692a1c7434da51fc1399ea2fa155d4fc983084ea59d1455afc79fafed
What I need to do is format it for my database so it reads as follows:
<ece42416 92a1c743 4da51fc1 399ea2fa 155d4fc9 83084ea5 9d1455af c79fafed>
I assume the easiest way to do this would be using regular expressions, but I have never used them before, and this is the first time I have ever needed to, and to be honest, I simply don't have the time to read up on them at the moment, so if anyone could help me with this I would be eternally grateful.
What about:
string input ="ece4241692a1c7434da51fc1399ea2fa155d4fc983084ea59d1455afc79fafed";
string target = "<" + Regex.Replace(input, "(.{8})", "$1 ").Trim() + ">";
Or
string another = "<" + String.Join(" ", Regex.Split(input, "(.{8})")) + ">";
You might just be better served having a small static string parsing method to handle it. A regular expression might get it done, but unless you're doing a bunch in a batch you won't save enough in system resources for it to be worth the maintenance of a RegEx (if you're not already familiar with them I mean). Something like:
private string parseIt(string str)
{
if(str.Length % 8 != 0) throw new Exception("Bad string length");
StringBuilder retVal = new StringBuilder(str)
for (int i = str.Length - 1; i >=0; i=i-8)
{
retVal.Insert(i, " ");
}
return "<" + retVal.ToString() + ">";
}
Try
Regex.Replace(YOURTEXT, "(.{8})", "$1 ");

Categories