Validate Razor template - c#

How can I validate Razor template, which is used to render mail template.
string template = #"
My template
#if (Model.Condition { <span>is true</spaM> }"
I made two mistakes: missing closing bracket and wrong closing tag.
I need to validate it and known what should I fix (the best is to known in which line). I would like to use native Razor methods.

If I understand correctly, you want to be notified that the code you've written in the Template is invalid HTML.
If so, I'm afraid there is no easy way. The Template is purely producing text that you specify to go out to the response.
It may not even be HTML - could be JavaScript or a number of other outputs - it's just a string of text.
You may have a Template that produces the start of a table, another that produces the body, and another that produces the footer and end table tags. Each of these would produce invalid HTML on their own, but output one after the other would produce a valid HTML table. (That's a lot of produces there - sorry).
What would make it invalid is the parser of the HTML - i.e. the browser. You would only be able to validate your Template output when it is in a complete document that can then be parsed.

You mean ?
#{
string template = Model.Condition ? "My template <span>is true</span>" : "";
}

string MyString = string.empty;
#if(Model.Condition)
{
MyString ="<span>"+ "is true"+"</span>";
}

Related

Verbatim string literal not interpreting html

In my controller action, I am sending a message to a view -
model.Result = ex.Message;
model.Result = model.Result + #" If you would like to create one, please click here ";
So, I want the message to show up like so -
The member doesn't exist. If you would like to create one, please click here.
But what actually shows up is
The member doesn't exist. If you would like to create one, please <a href> click here </a>.
So, I have 2 questions -
1) Why is the verbatim string literal not evaluating the html.
2) Is there a better way of doing this? I don't like having html in my controllers, but I also don't want to over architect things for a line of html.
Razor automatically HTML-encodes strings for security (to prevent script injection). You need to use Html.Raw if you want the actual HTML.
#Html.Raw(Model.ResultMessage)

Razor - write something unencoded without using html helper

I'm looking for a way to write a value in my razor view, without encoding it, AND without using the Html Helper.
I'm rendering the view in a hybrid website, where I parse my View programmatically, like this:
string html = "<html>#("Write something <strong>unencoded</strong>"</html>")
html = Razor.Parse<TModel>(html, model);
So essentially, my html variable contains a template containing razor c# code. Because I am compiling my view like this, I have no access to the Html helper (the accepted answer in this post implies this is indeed the case: How to render a Razor View to a string in ASP.NET MVC 3?)
However, my html variable also contains a statement like this:
#Html.Raw("<strong>This should be printed unencoded</strong>")
This does not work but gives "Html is not available in this context".
How can I achieve the same behavior? Using Response.Write gives the exact same error.
Are there any other ways?
Note: this is a hybrid website, containing both classic ASP webforms and some newer Web API and MVC stuff. The View I'm using is NOT accessed through conventional MVC ways.
HtmlString type of string should work for you.
Represents an HTML-encoded string that should not be encoded again.
Sample with creating such string inline (normally you'd have such values in Model set by controler):
#(new HtmlString("<strong>This should be printed unencoded</strong>"))
It took me a while to figure out, but this is the final solution (which works for me, but has some security implications, so do read on!)
Compile your view like this
var config = new TemplateServiceConfiguration();
config.EncodedStringFactory = new RawStringFactory();
var service = RazorEngineService.Create(config);
html = service.RunCompile(html, "templateNameInTheCache", null, model);
As you can see, I employed the RawStringFactory to make sure no HTML at all gets encoded. Of course, MVC automatically encodes HTML as a safety precaution, so doing this isn't very safe. Only do this if you're 100% sure that all of the output in the entire Razor view is safe!

Bold Text in Html.FormatValue using Razor

I want to have the following result. Username has to be bold:
Blabla Username Bla.
I have the Format in a ressource file:
Blabla {0} Bla.
And in the view I do the following:
#Html.FormatValue(User.Identity.Name, Resources.MyFormatString)
How can I make the Username bold and use Html.FormatValue? Or is there another method to achieve this?
You could simply change your resource to contain the bold-tag, strong-tag or a style.
Like "Blabla <b>{0}</b> Bla.".
[edit]
Indeed, checked Html.FormatValue for an escape functionality, did not see one, but apparently it does :)
In that case using #Html.Raw and string.Format will work.
#Html.Raw(string.Format(Resources.MyFormatString, "SomeName"))
(tested in MVC 5, but #Html.Raw is also available in 4)
Also a small note: storing HTML in resources is probably not the best idea, mixing UI & content.
[/edit]
I wanted to solve your example with including html tags, be safe with html characters in the resources, and safely include user input or html tags. My solution of your example is
#(Resources.MyFormatString.FormatWithHtml(
"<b>" + HttpUtility.HtmlEncode(User.Identity.Name) + "</b>"))
using my function FormatWithHtml
/// Encodes to MvcHtmlString and includes HTML tags or already encoded strings, placeholder is the '|' character
public static MvcHtmlString FormatWithHtml (this string format, params string[] htmlIncludes)
{
var result = new StringBuilder();
int i = -1;
foreach(string part in format.Split('|')) {
result.Append(HttpUtility.HtmlEncode(part));
if (++i < htmlIncludes.Length)
result.Append(htmlIncludes[i]);
}
return new MvcHtmlString(result.ToString());
}
One more example, this
#("Resource is safe to html characters <&> and will include |format tags| or any | user input."
.FormatWithHtml("<b>", "</b>", "<b id='FromUser'>" +HttpUtility.HtmlEncode("<a href='crack.me'>click</a>") +"</b>"))
will write to your razor page
Resource is safe to html characters <&> and will include format tags or any <a href='crack.me'>click</a> user input.

Object to string using Razor?

Is there an Razor method that will allow to put "object to string" inside html like:
Anchor
Or do I have to use something like that and change my model?
c# object to string to display it in text format
Thanks
if the link you are passing from your model is a string the correct syntax would be
Anchor
or
<a href=#Html.Raw("http://www." + #Model.x.y))>Anchor</a>
This way you are correctly parsing any special characters which might occur in the link like & or =

C# HtmlEncode, then Javascript insert using .innerHTML

What follows is a piece of text that gets HtmlEncoded in C# before being sent to the browser (during a callback). Once received, in Javascript I do myDiv.innerHTML = theStringBelow;
<span xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
xmlns:SharePoint="Microsoft.Sharepoint.WebControls"
xmlns:ext="my_namespace:my_xslt_extension">Some text to be shown.</span>
However, what results is that I simply see the exact text shown above. It isn't being treated as an html element that got added to the DOM, but as plain text. When I add the exact same text through javascript (e.g., I skip the callback, and just say myDiv="exactString") it DOES get added correctly (it gets treated as a span).
What is going on? Do I have to un-encode it? Should I not have encoded to begin with?
Edit
The question still stands for curiosity's sake, but I have fixed the issue simply by not HtmlEncoding the data. An earlier issue must have added onto this one, making me think the HtmlEncoding was still necessary.
You should not HTMLEncode it if it is to become HTML nodes. What HTML encoding will do is turn your string from above into this:
<span xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
xmlns:SharePoint="Microsoft.Sharepoint.WebControls"
xmlns:ext="my_namespace:my_xslt_extension">Some text to be shown.</span>
Try passing the string in as it is. You will of course have to escape the string. But once it has become a string in JavaScript it should be unescaped as it is being made into a string in memory. Then you should be able to do the div.innerHTML call and get your expected result. The escaping of the string can probably be accomplished by doing the following:
// in your .cs code-behind/view/whatever.
string = string.replace("""", "\""");
Which should produce:
<span xmlns:asp=\"http://schemas.microsoft.com/ASPNET/20\"
xmlns:SharePoint=\"Microsoft.Sharepoint.WebControls\"
xmlns:ext=\"my_namespace:my_xslt_extension\">Some text to be shown.</span>
Which you can then output like so:
// in your webform/view
<script type="text/javascript">
var mystring;
mystring = "<%=string;%>";
</script>
Let me know how that works out for you.
HTML Encode will turn < into < and so on. This breaks HTML Formatting and is used so blocks of text like this:
Insert <name> here
Does not turn out like this:
Insert here
If your intent is to have the <span ... get inserted into the html directly you either need to NOT encode it on the way out, or if that will disrupt transmission, you need to decode it in js before you set the .innerHTML part.

Categories