Scenario
In my app I parse text, links and tags to HTML using Razor.Parse<>().
string Razor.Parse<TEmail>(string razorTemplate, TEmail model) where TEmail : BaseEmail
I use '#' to parse data from model. I also parse web links. This feature works fine, till I parse Google Map links e.g.
Problem
https://www.google.com/maps/place/New+York,+NY,+USA/#40.6974034,-74.1197634,11z/data=!3m1!4b1!4m5!3m4!1s0x89c24fa5d33f083b:0xc80b8f06e177fe62!8m2!3d40.7127753!4d-74.0059728
Link includes '#'. So I get error:
RazorEngine.Templating.TemplateParsingException: '"40.6974034" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.'
My try
I try to parse html with dobule ##
https://www.google.com/maps/place/New+York,+NY,+USA/##40.6974034,-74.1197634,11z/data=!3m1!4b1!4m5!3m4!1s0x89c24fa5d33f083b:0xc80b8f06e177fe62!8m2!3d40.7127753!4d-74.0059728
But i get error:
RazorEngine.Templating.TemplateParsingException: '"#" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.'
Any idea what can I do? Thank you
This is because you are trying to pass something that is invalid. when you use the "#" keyword you cannot pass values, you must pass an identifier, keyword, comment, "(", "{". The "#" keyword marks the beginning of a code block for example:
string value = Razor.Parse("#UserSession.NumberOfPeople")
The above will work but this:
string value = Razor.Parse("#http://www.something.com")
won't work, this is invalid.
What you need to do is find an alternative.
you need to use razor engine. If you have no idea it is,
read here. You cannot esacpe #, because Razor.parse does not escape strings.
Related
I am reading a C# source file.
When I encounter a string, I want to get it's value.
For instance, in the following example:
public class MyClass
{
public MyClass()
{
string fileName = "C:\\Temp\\A Weird\"FileName";
}
}
I would like to retrieve
C:\Temp\A Weird"FileName
Is there an existing procedure to do that?
Coding a solution with all the possible cases should be quite tricky (#, escape sequences. ...).
I am convinced such procedure exists...
I would like to have the dual function too (to inject a string into a C# source file)
Thanks in advance.
Philippe
P.S:
I gave an example with a filename, but I look for a solution working for all kinds of strings.
I'm pretty sure you can use CodeDOM to read a C# code file and parse its elements. It generates a code tree, and then you can look for nodes representing strings.
http://www.codeproject.com/Articles/2502/C-CodeDOM-parser
Other CodeDom parsers:
http://www.codeproject.com/Articles/14383/An-Expression-Parser-for-CodeDom
NRefactory: https://github.com/icsharpcode/NRefactory and http://www.codeproject.com/Articles/408663/Using-NRefactory-for-analyzing-Csharp-code
There is a way of extracting these strings using a regular expression:
("(\\"|[^"])*")
This particular one works on your simple example and gives the filename (complete with leading and trailing quote characters); whether it would work on more complex ones I can't easily tell unfortunately.
For clarity, (\\"|[^"]) matches any character apart from ", except where it has a leading \ character.
Just use ".*" Regex to match all string values, then remove trailing inverted commas and unescape it.
this will allow \" and "" characters inside your string
so both "C:\\Temp\\A Weird\"FileName" and "Hello ""World""" will match
I am trying to format a Json input to a JSON RPC. For example, the JSON am goint to post is as following,
"{"filter":{ "Ids": [123, 124], "Types":["EMPLOYEE"]}}"
which I expect to return users with id 123, 124 and of type EMPLOYEE. But for the Ids parameter, I want to may it dynamic so that I can set the value in my C# calling method like the following
string.Format("{\"filter\":{ \"Ids\": [{0}], \"Types\":[\"EMPLOYEE\"]}}", "123, 124");
when doing so, I get the format exception "Input string was not in correct format"....
I know, I can build up the string using string.concat or string builder. Am just curious, if there is any solution to overcome this string.format exception in the event when a string has curly brackets (am assuming this is the cause of the exception) already.
You have to escape "{" and "}"-chars by using "{{" resp. "}}".
See "Escaping Braces" in http://msdn.microsoft.com/en-us/library/txafckwd.aspx.
I am trying to add a new line Javascript alert message. I tried '\n' and 'Environment.NewLine'. I am getting Unterminated string constant error. Could you please let me know what could be the problem? I appreciate any help. I also tried \r\n.
string msg = "Your session will expire in 10 minutes. \n Please save your work to avoid this.";
if (!this.ClientScript.IsStartupScriptRegistered(ID))
this.ClientScript.RegisterStartupScript(GetType(), ID, String.Format("<script language=JavaScript>setTimeout(\'alert(\"{1}\");\',{0}*1000);</script>", sTime, msg));
I would suspect that you need to change your code to;
string msg = "Your session will expire in 10 minutes. \\n Please save your work to avoid this.";
And escape the \n otherwise your code outputted would actually include the line break rather than \n
Your output code would look like:
setTimeout('alert("Your Session....
Please save your work to ....");', 1000);
Rather than:
setTimeout('alert("Your Session....\n Please save your work to ....");', 1000);
I'm not sure, but I think that \n is escaped in the string.Format method, like \". Maybe you should use \\n instead.
Edited : and the first \ of \\n has been escaped when i posted that. xD
At first glance I would say the primary problem is that you're escaping the ' character around your alert. Since your string is defined by the double quotes, you don't need to escape this character.
add "#" at the beginning of your string - like this:
string msg = #"Your session ....";
The code looks fine, so I'm going to guess that you're using a message that itself has a ' quote in it, causing the JS syntax error. For inserting dynamic text into a Javascript code block, you really should use JSON to make your C# strings 'safe' for use in JS.
Consider JSON the go-to method for preventing the JS equivalent of SQL injection attacks.
Adding a # at the beginning should help.
I am using HighCharts and am generating script from C# and there's an unfortunate thing where they use inline functions for formatters and events. Unfortunately, I can't output JSON like that from any serializer I know of. In other words, they want something like this:
"labels":{"formatter": function() { return Highcharts.numberFormat(this.value, 0); }}
And with my serializers available to me, I can only get here:
"labels":{"formatter":"function() { return Highcharts.numberFormat(this.value, 0); }"}
These are used for click events as well as formatters, and I absolutely need them.
So I'm thinking regex, but it's been years and years and also I was never a regex wizard.
What kind of Regex replace can I use on the final serialized string to replace any quoted value that starts with function() with the unquoted version of itself? Also, the function itself may have " in it, in which case the quoted string might have \" in it, which would need to also be replaced back down to ".
I'm assuming I can use a variant of the first answer here:
Finding quoted strings with escaped quotes in C# using a regular expression
but I can't seem to make it happen. Please help me for the love of god.
I've put more sweat into this, and I've come up with
serialized = Regex.Replace(serialized, #"""function\(\)[^""\\]*(?:\\.[^""\\]*)*""", "function()$1");
However, my end result is always:
formatter:function()$1
This tells me I'm matching the proper stuff, but my capture isn't working right. Now I feel like I'm probably being an idiot with some C# specific regex situation.
Update: Yes, I was being an idiot. I didn't have a capture around what I really wanted.
`enter code here` serialized = Regex.Replace(serialized, #"""function\(\)([^""\\]*(?:\\.[^""\\]*)*)""", "function()$1");
that gets my match, but in a case like this:
"formatter":"function() { alert(\"hi!\"); return Highcharts.numberFormat(this.value, 0); }"
it returns:
"formatter":function() { alert(\"hi!\"); return Highcharts.numberFormat(this.value, 0); }
and I need to get those nasty backslashes out of there. Now I think I'm truly stuck.
Regexp for match
"function\(\) (?<code>.*)"
Replace expression
function() ${code}
Try this : http://regexr.com?30jpf
What it does :
Finds double quotes JUST before a function declaration and immediately after it.
Regex :
(")(?=function()).+(?<=\})(")
Replace groups 1 & 3 with nothing :
3 capturing groups:
group 1: (")
group 2: ()
group 3: (")
string serialized = JsonSerializer.Serialize(chartDefinition);
serialized = Regex.Replace(serialized, #"""function\(\)([^""\\]*(?:\\.[^""\\]*)*)""", "function()$1").Replace("\\\"", "\"");
i tried to call a javascript function from codebehind(c#.net) with a parameter string parameter consisting of all alphabetic characters (eg: function1("fsdadfa");) and failed to get it worked. But when i changed the alphabetic characters with all numeric ones (eg:function1("12234");) it worked.
My code is as follows:
i used string.Format to call the function. My code is as follows:
string.Format("javascript:OpenNewsletter1({0},{1})",reader.GetInt("Id").ToString(),"dcsfs")
the problem arises with the 2nd parameter.
Any body know why it happened? if so please help me.
You need to encode it and use quotes:
string.Format("javascript:OpenNewsletter1({0}, '{1}')",
reader.GetInt("Id").ToString(),
HttpUtility.HtmlEncode("dcsfs"))
Notice the single quotes around the second parameter as well as encoding it because if the value contains special characters it might break your code.
The parameter is inserted in the format string as-is, so
string.Format("javascript:OpenNewsletter1({0},{1})",123,"dcsfs")
yields
javascript:OpenNewsletter1(123,dcsfs)
where javascript interprets dcsfs as a variable name.
Try
string.Format("javascript:OpenNewsletter1({0},'{1}')",123,"dcsfs")
which will yield
javascript:OpenNewsletter1(123,'dcsfs')
that javascript will know to handle as a string literal.
I think you'll need to add quotes around the string (parameter {1}) for javascript:
string.Format(
"javascript:OpenNewsletter1({0},\"{1}\")",
reader.GetInt("Id").ToString(),
"dcsfs")