How to serialize an object with newtonsoft, which has a value with backslash [\] - vb.net

I prepared this small example to show you my problem (vb.net and Newtonsoft)
I would prefer that the solution be done with Newtonsoft.
Public Class Message
Property Emoji As String
End Class
Public Sub GetJson()
Dim msgObject As New Message With {.Emoji = "\uD83D\uDE00"}
'Option 1
Dim JsonSerializerSettings As New JsonSerializerSettings
JsonSerializerSettings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii
Dim msgJson_1 As String = Newtonsoft.Json.JsonConvert.SerializeObject(msgObject, JsonSerializerSettings)
'Option 2
Dim msgJson_2 As String = Newtonsoft.Json.JsonConvert.SerializeObject(msgObject, Newtonsoft.Json.Formatting.None)
'Option 3
Dim stringWriter As New StringWriter()
Using writer As New JsonTextWriter(stringWriter)
writer.Formatting = Formatting.None
Dim serializer As New JsonSerializer()
serializer.Serialize(writer, msgObject)
End Using
Dim msgJson_3 As String = stringWriter.ToString()
End Sub
with none of the three options works, it always results in
{
"Emoji": "\\uD83D\\uDE00"
}
The result I need is
{
"Emoji": "\uD83D\uDE00"
}
How do I set Newtonsoft to not take into account the backslash character, as an escaped character?
Another unorthodox way could be:
jsonString = jsonString.replace("\\","\")
I do not really like
Thanks!!!!

\ is an escape char in JSON hence if you try and serialise a \ it gets escaped as \\ then when you deserialise \\ you get \
My guess is you have been given an example asking you to send "Emoji": "\uD83D\uDE00"
In json (and C#) \u#### specifies a unicode character (usually for something not found on a keyboard) as you are using VB.NET instead you should use $"{ChrW(&HD83D)}{ChrW(&HDE00)}"

"jsonString = jsonString.replace("//","/") " will never work, this is more safe way
json = json.Replace("\\\\u","\\u");
or since you don't like old, good classical solutions
json = Regex.Replace(json, #"\\u", #"u");
//or
json = json.Replace(#"\\u", #"\u");
even this will work in your case ( but I will not recommend for another cases since it is not safe)
json = Regex.Unescape(json);

Related

How can I get the same MD5 hash from both AS3 and VB.NET? Already have code, it doesn't work

I need to generate a hash of a file in VB.NET on a server and send it to an AS3 client for validation against a file on the client. I chose MD5. I am using the builtin VB.NET MD5 hash and the hurlant MD5 hash on AS3. The results are different.
I am looking for a moderately reliable method of verifying the files are the same. Speed is as important as accuracy. I am open to other hashing algorithms which are at least as reliable/secure as MD5.
If there is a solution using what I have that would be great. If there is another way which works, that's OK too.
My VB Code looks like;
Dim baFileData() As Byte = File.ReadAllBytes(HttpContext.Current.Server.MapPath(strFilePath))
Dim strFileHash As String = GetHash(baFileData)
Function GetHash(theInputBytes() As Byte) As String
Using hasher As MD5 = MD5.Create() ' create hash object
' Convert to byte array and get hash
Dim dbytes As Byte() =
hasher.ComputeHash(theInputBytes)
' sb to create string from bytes
Dim sBuilder As New StringBuilder()
' convert byte data to hex string
For n As Integer = 0 To dbytes.Length - 1
sBuilder.Append(dbytes(n).ToString("X2"))
Next n
Return sBuilder.ToString()
End Using
End Function
My AS3 code looks like this;
private function getFileMD5Hash(flLocalFile:File):String
{
var strmInFile:FileStream = new FileStream();
strmInFile.open(flLocalFile, FileMode.READ);
var strFileData:String = strmInFile.readUTFBytes(strmInFile.bytesAvailable);
strmInFile.close();
var hash:IHash = Crypto.getHash("md5");
var baFileData:ByteArray = Hex.toArray(Hex.fromString(strFileData));
var baHash:ByteArray = hash.hash(baFileData);
var strFileHash:String = Hex.fromArray(baHash);
return strFileHash;
}
#Organis basically gave me the tools in his comments to solve the problem. My only reason for posting this as an answer is to show what the resulting code looks like.
If Organis posts an answer I will give it a vote.
The VB code remained the same.
The AS3 code changed to;
private function getFileMD5Hash(flLocalFile:File):String
{
var strmInFile:FileStream = new FileStream();
strmInFile.open(flLocalFile, FileMode.READ);
var baFileData:ByteArray = new ByteArray;
strmInFile.readBytes(baFileData);
strmInFile.close();
var hash:IHash = Crypto.getHash("md5");
var baHash:ByteArray = hash.hash(baFileData);
var strFileHash:String = Hex.fromArray(baHash).toUpperCase();
return strFileHash;
}

Using Flurl in vb.net

How can I use Flurl in VB.NET for GET and POST? I installed the NuGet package and imported Flurl.
How can I translate this C# code to VB?
var responseString = await "http://www.example.com/recepticle.aspx"
.PostUrlEncodedAsync(new { thing1 = "hello", thing2 = "world" })
.ReceiveString();
First, import the relevant namespace:
Imports Flurl.Http
..and then this should work:
Dim responseString = Await "http://www.example.com/recepticle.aspx".
PostUrlEncodedAsync(New With {.thing1 = "hello", .thing2 = "world"}).
ReceiveString()
Explanation:
In VB.NET, when declaring an anonymous object, you should use New With instead of new. Also, the properties must be preceded by a dot ..
When breaking statements into multiple lines, the dot can't be at the beginning of the line so we add it at the end of the previous line. If you prefer to start the next line with a dot. You may end the previous line with the line-continuation character _ like this:
Dim responseString = Await "http://www.example.com/recepticle.aspx" _
.PostUrlEncodedAsync(New With {.thing1 = "hello", .thing2 = "world"}) _
.ReceiveString()
For more information, see: Continuing a statement over multiple lines

VB.NET String.Format FormatException was unhandled

I want to generate a json string but
What did I do is wrong? Why to this code throws an An unhandled exception
Public Function GenerateJsonString(doer As Integer, comment As String, id As Integer) As String
Dim jsonString As String = String.Format("{done_by:{0}, comment:{1}, request_id:{2}}", doer, comment, id)
Return jsonString
End Function
An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll
Additional information: Input string was not in a correct format.
The bracket { is a special character in string.format so you need to use two brackets if you want them in the output like so:
Dim jsonString As String = String.Format("{{done_by:{0}, comment:{1}, request_id:{2}}}", 806, "comment", 16233)
It outputs
{done_by:806, comment:comment, request_id:16233}
Which is not valid json since it's missing the "-characters. So to correct that you could do
Dim jsonString As String = String.Format("{{""done_by"":{0}, ""comment"":""{1}"", ""request_id"":{2}}}", 806, "comment", 16233)
Note that comment is string and also needs the "-characters in value.
Output is correct json:
{"done_by":806, "comment":"comment", "request_id":16233}
There is also easier and more robust way to do this by serialization:
Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer
Dim jsonString As String = serializer.Serialize(New With {.done_by = 806, .comment = "comment", .request_id = 16233})
If you have class library or windows -project it needs System.Web.Extensions reference to your project.
Good luck!
The issue is the fact that you have braces in your literal text. When calling String.Format, braces are used to indicate place-holders but you have an opening brace at the beginning of the text and a closing brace at the end. If you want those literal braces included then you must escape them, i.e.
"{{done_by:{0}, comment:{1}, request_id:{2}}}"

Index (zero based) must be greater than or... Working with the Bit.ly API

I'm working (actually more like playing) around with the Bit.ly API, and keep getting the error in the title of this question. So I'm going to show you the code and hopefuly someone can help me resolve this. First the client side code.
var x = service.GetClicks(url, service.BitlyLogin, service.BitlyAPIKey);
Console.WriteLine(x);
Console.ReadLine();
And this is the code that's being called
public List<int> GetClicks(string url, string login, string key)
{
List<int> clicks = new List<int>();
url = Uri.EscapeUriString(url);
string reqUri =
String.Format("http://api.bit.ly/v3/clicks?" +
"login={0}&apiKey={1}&shortUrl={2}&format=xml" +
login, key, url);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
req.Timeout = 10000; // 10 seconds
Stream stm = req.GetResponse().GetResponseStream();
XmlDocument doc = new XmlDocument();
doc.Load(stm);
// error checking for xml
if (doc["response"]["status_code"].InnerText != "200")
throw new WebException(doc["response"]["status_txt"].InnerText);
XmlElement el = doc["response"]["data"]["clicks"];
clicks.Add(int.Parse(el["global_clicks"].InnerText));
clicks.Add(int.Parse(el["user_clicks"].InnerText));
return clicks;
}
As you can see it's very simple code, nothing complicated, and I can see nothing that causes this error. Anyone out there who has worked with(the full error is Index (zero based) must be greater than or equal to zero and less than the size of the argument list.) the Bit.ly API and can lend a hand?
Instead this
string reqUri =
String.Format("http://api.bit.ly/v3/clicks?" +
"login={0}&apiKey={1}&shortUrl={2}&format=xml" + login, key, url);
Use this
string reqUri = String.Format("http://api.bit.ly/v3/clicks?login={0}&apiKey={1}&shortUrl={2}&format=xml", login, key, url);
Notice that I just changed the plus sign with the comma before "login, key, url);" at the end of the String.Format().
I narrowed it down to a place where I was using string.Format to build an array and has less in the string.Format than what was supposed to. I had it go to Index 3 but only filled to Index 2
Not for your specific case, but I ran into this: make sure that, if you have multiple parameters, you send them as an array of objects instead of an IEnumerable:
IEnumerable<object> myArgs = ...;
string toFormat = "{0} xyz {1}";
String.Format(toFormat, myArgs);
// ERROR, since myArgs is one argument whereas the string template requires two
String.Format(toFormat, myArgs.ToArray());
// Valid, as the Format() accepts an array of objects to fill all arguments in the string

Problem while sending JSON DATA

I have to pass my Json data in a particular format.
My app is coded in vb.
The following is my code :
Dim jsonObject As New Json.JsonObject
jsonObject.Item("count") = New Json.JsonNumber("0")
jsonObject.Item("data") = New Json.JsonArray("")
**jsonObject.Item("success") = New Json.JsonString("True")**
The Problem lies in the line :
jsonObject.Item("success") = New Json.JsonString("True") .
The error message being shown is " Type 'Jayrock.Json.JsonString' has no constructors."
Just to add i have imported the associated libraries .
What should I do to tackle this problem ??
Try simply like this:
Dim jsonObject As New Json.JsonObject
jsonObject.Item("count") = 0
jsonObject.Item("data") = New Json.JsonArray()
jsonObject.Item("success") = "True"
In other words, you can use primitive types like string and integer as values.