VB.NET String.Format FormatException was unhandled - vb.net

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}}}"

Related

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

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);

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

Transform String concatenation into String.format with parameters

Is the a way to make Intellij Idea to extract concatenated strings into String that uses String.format with parameteres, like:
transform:
String parameter = "the parameter";
String message = "the parameter of the message is: "+parameter;
into:
String parameter = "the parameter";
String message = String.format("the parameter of the message is: %s", parameter);
Now I found it. I thought it should be in the Refactor This/Extract menu:

String interpolation outputs enum name instead of value

I was hoping someone can explain this default functionality regarding string interpolation and the enum type.
I have this enum:
public enum CommentType
{
MyComment = 24,
TheirComment = 25,
AnotherComment = 26
}
I am using it in a string:
Dim sDateModified As String
sDateModified = $"<div name='commenttype{CommentType.MyComment}'></div>"
I was expecting CommentType.MyComment to be evaluated and the int value 24 to be used. The result should be: <div name='commenttype24'></div>
But what actually happens is that the identifier is used instead, giving me: <div name='commenttypeMyComment'></div>
In order to get the enum value I had to convert it to an integer:
sDateModified = $"<div name='commenttype{Convert.ToInt32(CommentType.MyComment)}'></div>"
It just feels counter intuitive to me. Can someone explain or point me to documentation on why it works this way?
You're getting the string value MyComment because that's what is returned by:
CommentType.MyComment.ToString()
Methods like String.Format and Console.WriteLine will automatically call ToString() on anything that isn't already a string. The string interpolation syntax $"" is just syntactic sugar for String.Format, which is why string interpolation also behaves this way.
Your workaround is correct. For slightly more compact code, you could do:
CInt(CommentType.MyComment)
You just need to use a format string in the interpolated value to force the result to integer format.
Dim sDateModified As String
sDateModified = $"<div name='commenttype{CommentType.MyComment:D}'></div>"

How to filter out some vulnerability causing characters in query string?

I need to filter out characters like /?-^%{}[];$=*`#|&#'\"<>()+,\. I need replace this with empty string if it is there in the query string. Please help me out. I am using this in ASP pages.
Best idea would be to use a function something along the lines of:
Public Function MakeSQLSafe(ByVal sql As String) As String
'first i'd avoid putting quote chars in as they might be valid? just double them up.
Dim strIllegalChars As String = "/?-^%{}[];$=*`#|&#\<>()+,\"
'replace single quotes with double so they don't cause escape character
If sql.Contains("'") Then
sql = sql.Replace("'", "''")
End If
'need to double up double quotes from what I remember to get them through
If sql.Contains("""") Then
sql = sql.Replace("""", """""")
End If
'remove illegal chars
For Each c As Char In strIllegalChars
If sql.Contains(c.ToString) Then
sql = sql.Replace(c.ToString, "")
End If
Next
Return sql
End Function
This hasn't been tested and it could probably be made more efficient, but it should get you going. Wherever you execute your sql in your app, just wrap the sql in this function to clean the string before execution:
ExecuteSQL(MakeSQLSafe(strSQL))
Hope that helps
As with any string sanitisation, you're much better off working with a whitelist that dictates which characters are allowed, rather than a blacklist of characters that aren't.
This question about filtering HTML tags resulted in an accepted answer suggesting the use of a regular expression to match against a whitelist: How do I filter all HTML tags except a certain whitelist? - I suggest you do something very similar.
I'm using URL Routing and I found this works well, pass each part of your URL to this function. It's more than you need as it converts characters like "&" to "and", but you can modify it to suit:
public static string CleanUrl(this string urlpart) {
// convert accented characters to regular ones
string cleaned = urlpart.Trim().anglicized();
// do some pretty conversions
cleaned = Regex.Replace(cleaned, " ", "-");
cleaned = Regex.Replace(cleaned, "#", "no.");
cleaned = Regex.Replace(cleaned, "&", "and");
cleaned = Regex.Replace(cleaned, "%", "percent");
cleaned = Regex.Replace(cleaned, "#", "at");
// strip all illegal characters like punctuation
cleaned = Regex.Replace(cleaned, "[^A-Za-z0-9- ]", "");
// convert spaces to dashes
cleaned = Regex.Replace(cleaned, " +", "-");
// If we're left with nothing after everything is stripped and cleaned
if (cleaned.Length == 0)
cleaned = "no-description";
// return lowercased string
return cleaned.ToLower();
}
// Convert accented characters to standardized ones
private static string anglicized(this string urlpart) {
string beforeConversion = "àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇ’ñ";
string afterConversion = "aAaAaAaAeEeEeEeEiIiIiIoOoOoOuUuUuUcC'n";
string cleaned = urlpart;
for (int i = 0; i < beforeConversion.Length; i++) {
cleaned = Regex.Replace(urlpart, afterConversion[i].ToString(), afterConversion[i].ToString());
}
return cleaned;
// Spanish : ÁÉÍÑÓÚÜ¡¿áéíñóúü"
}