Razor engine display angle brackets in markdown [duplicate] - c#

I am trying to generate emails with HTML content. this content has already gone through sanitation so I am not worried in that regard, however when I call:
Razor.Parse(template, model);
on the following Razor template:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body>
#(new System.Web.HtmlString(Model.EmailContent))
</body>
</html>
the email that is outputted is HTMl encoded, but I need it decoded. How can I accomplish this?

RazorEngine, like MVC's Razor View Engine, will automatically encode values written to the template. To get around this, we've introduce an interface called IEncodedString, with the default implementations being HtmlEncodedString and RawString.
To use the latter, simply make a call to the inbuilt Raw method of TemplateBase:
#Raw(Model.EmailContent)

FYI I have a fork that includes the #Html.Raw(...) syntax here:
https://github.com/Antaris/RazorEngine/pull/105

I am using RazorEngine 3.8.2 and #Raw(Model.Content) is working perfectly fine for me.

If you have a custom base class for your templates, you can code Write method to behave similar to normal MVC template: if the output value is IHtmlString it should not encode it.
Here's the code I'm using in my TemplateBase class:
// Writes the results of expressions like: "#foo.Bar"
public virtual void Write(object value)
{
if (value is IHtmlString)
WriteLiteral(value);
else
WriteLiteral(AntiXssEncoder.HtmlEncode(value.ToString(), false));
}
// Writes literals like markup: "<p>Foo</p>"
public virtual void WriteLiteral(object value)
{
Buffer.Append(value);
}

Built a wrapper for RazorEngine that adds in support for #Html.Raw() and #Html.Partial()
https://github.com/b9chris/RazorEngineComplete

Related

Building HTML Twitter Bootstrap 3 in code

.NET 4.51 Webforms
I an writing some user controls and need to generate some HTML for Twitter Bootstrap 3. I was wondering if anyone had come across a class that would assist with this before I roll my own?
There seems to be an abundance of HTML helpers for MVC https://www.twitterbootstrapmvc.com/ but nothing where I can generate HTML from code behind easily. Yes I can use something like HTML helpers in Webform? or http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper_methods(v=vs.118).aspx or http://msdn.microsoft.com/en-us/library/system.web.mvc.tagbuilder(v=vs.111).aspx but if there is something out there already then I would rather use that than rolling my own.
Has anyone come across anything like this?
If your're talking about textboxes, textareas and so on, the best way to do it is by making a function that adds your custom html attributes to that element.
After that you should do method which returns MvcHtmlString
public static MvcHtmlString CustomTextBox(this HtmlHelper helper.....)
{
var attributes= customFunctionsToSetAttributes // Dictionary<string,object>
helper.TextBox(name, value, format, attributes); // mvc original .TextBox helper
}

How can I insert HTML tags in C# string property?

Not sure how if it is possible, but I have this in a class:
public string TextNotIncluded
{
get
{
return ("which is <u>not</u> included in the Quote");
}
}
The <u> and </u> are being displayed in my view, rather than the word not being underlined. I am not familiar with C#.
Can anyone provide a quick answer?
Thanks.
Edit:
I am just calling this in my view thusly: #MyClass.TextNotIncluded. Wrapping it with #Html.Raw is not efficient in my case because I have this sprinkled throughout dozens of views.
There's nothing fundamentally wrong with doing that but it probably won't render the way you're expecting.
You can use #Html.Raw as others have suggested, but I think it's better to explicitly declare your model in such a way as to indicate that it may contain html. You probably want to use the MvcHtmlString class for this instead:
public MvcHtmlString TextNotIncluded
{
get { return MvcHtmlString.Create("which is <u>not</u> included in the Quote"); }
}
Then in your view you can just use:
#Model.TextNotIncluded
If you're using Razor, strings are HTML-encoded by default - you'll need to use Html.Raw to turn off the encoding:
#Html.Raw(x.TextNotIncluded)
In the ASPX engine, you would use <%= %>
<%= x.TextNotIncluded %> - this gives you the raw text
<%: x.TextNotIncluded %> - this HTML-encodes your text - you don't want this.
To output raw HTML, use the Raw HTML helper:
#Html.Raw(TextNotIncluded)
This helper doesn't HTML encode the input, so be careful when using it.
You need to HTML encode the string. Most are recommending the MVC approach, but I would make it more independent of the presentation layer.
public string TextNotIncluded {
get {
return System.Web.HttpUtility.HtmlEncode("which is <u>not</u> included in the Quote");
}
}
You can use either
#Html.Raw(Model.TextNotIncluded)
or
#MvcHtmlString.Create(Model.TextNotIncluded)
in your view.
But it would be better to alter the return type of the property:
public MvcHtmlString TextNotIncluded
{
get
{
return MvcHtmlString.Create("which is <u>not</u> included in the Quote");
}
}

RazorTemplateEngine parser produces unusual syntax tree

I was looking for a way to to reuse my MVC Razor views as javascript templates for client side rendering, and found this library (Razor Client Template) which parses razor views into javascript functions.
It doesn't play ball with Razor engine version 2, and a little digging shows this is because the Razor engine's syntax tree has been overhauled. In an attempt to modify things, I've found some weird results from the RazorViewEngine parser.
I have a very simple view, like so:
#model Justis4.Models.EntityModel
<div>
#Model.PropertyOne
#Model.PropertyTwo
</div>
The razor client template library starts off with:
var host = new RazorEngineHost(newCSharpRazorCodeLanguage());
var engine = new RazorTemplateEngine(host);
var parserResults = engine.ParseTemplate(razorTemplate); //from string reader
var doc = parserResults.Document;
and then goes off to start parsing the resulting syntax tree into a javascript function.
When I debug through the syntax tree, I see some odd stuff. As I understand it, the Razor engine splits the view into "blocks" and "spans" of different types. But as in the picture, the model declaration at the top has been parsed as markup, not code. There are similar oddities, and as a result, the rest of the parsing to javascript fails.
The standard razor parser does not recognise the #model keyword. The #model keyword comes from the MvcCSharpRazorCodeParser class in the System.Web.Mvc assembly.
The main functionality for this comes from SetModelTypeCodeGenerator. This class makes use of the core razor engine class, SetBaseTypeCodeGenerator to change the base type for the razor view from the default WebViewPage to WebViewPage<Model>.
Solutions
Use the #inherits keyword instead e.g. #inherits WebViewPage<EntityModel>.
Or, add a reference to System.Web.Mvc and use a custom language change the code parser to MvcCSharpRazorCodeParser. You will need to set the RazorEngine.DefaultBaseClass property to a non-generic version of the base class you intend to use, e.g. for WebViewPage<T> you would set engine.DefaultBaseClass = "System.Web.Mvc.WebViewPage".
class MvcCSharpRazorCodeLanguage : CSharpRazorCodeLanguage
{
public override ParserBase CreateCodeParser()
{
return new MvcCSharpRazorCodeParser();
}
}

ASP.NET MVC: Get lowercase links (instead of Camel Case)

All my dynamically generated action links etc. are creating links like /Account/Setup. It looks strange.
I'd like all my links to be lowercase (meaning /account/setup). Any way to do this?
There is simpler solution in .NET Framework 4.5, a new property RouteCollection.LowercaseUrls, here's an example
Take a look at http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/. You can find more information in another stackoverflow at How can I have lowercase routes in ASP.NET MVC?.
The other posts thus far have not tackled the scenario where you navigate to the root of your web directory. If you have a mapping that directs to the HomeController Index action, you would like the following URL to appear:
mysite/home/ or even mysite/home/index
No amount of Html helper function usage will change the fact that, by default, the following will be shown in the browser location bar:
mysite/Home or mysite/Home/Index
Write an extension method for Html:
public static class MyHtmlExtensions
{
public static string LowerActionLink(this HtmlHelper htmlHelper,someargs)
{
return String.ToLowerInvariant(htmlHelper.ActionLink(someArgs));
}
}
Then use Html.LowerActionLink instead of Html.ActionLink

Can I stop .NET eating IDs?

I'm an Information Architect and JavaScript developer by trade nowadays, but recently I've been getting back into back-end coding again. And, whilst trying to get an HTML prototype integrated and working with our C#-based CMS, I've come to blows with our programmers over the HTML ID attributes being arbitrarily rewritten by .NET for form elements.
I can understand the code-behind reasoning for .NET changing IDs, but the fact you can no longer use IDs when trying to develop e.g. jQuery enhanced interfaces is causing some friction. What can I do to work around this?
I've tried using the class attribute instead, but that's really crappy, not what it's meant for and doesn't get around that problem of .NET effectively changing rendered source on the fly. It also means that CSS is less useful now and less efficient to create and maintain.
Any tips or advice greatly appreciated--anything for a few less sleepless nights...
The short answer is no, with webforms the id can always be rewritten depending on the nesting of the element. You can get access to the id through the ClientID property, so you could set the ids into variables in a script at the end of the page/control then put them into jQuery.
something like this:
<asp:button id="ImAButton" runat="server">Click Me</asp:button>
<script type="text/javascript">
var buttonId = "<%=ImAButton.ClientId%>";
$("#"+buttonId).bind('click', function() { alert('hi); });
</script>
It's a hack I know, but it will work.
(I should note for the un-initiated, I'm using the Prototype $ get by id method there)
One method is to override the ID's manually:
public override string UniqueID
{
get { return this.ID; }
}
public override string ClientID
{
get { return this.ID; }
}
Rick Strahl wrote a blog post with some more information on that approach.
Look at ASP.Net MVC - it addresses the over-kill object hierarchies that ASP.Net generates by default.
This site is written in MVC (I think) - look at it's structure. Were I working on a new project right now I would consider it first
If you're stuck with basic ASP.Net then be careful overriding the ClientID and UniqueID - it tends to break many web controls.
The best way I've found is to pass the unreadable ClientID out to the Javascript.
You can extend .net controls and make them return actual id's when related properties are called.
ClientID is the id attribute and UniqueID is the name attribute of html elements. So when you create a textbox like the following and using this instead of the textbox in framework, you make id and name attributes render as the same as the server-side id.
public class MyTextBox : TextBox
{
public override string ClientID { get { return ID; } }
public override string UniqueID { get { return ID; } }
}
To use this new user control, basically register this control as you would do for a custom user control (you can do is in web.config so you won't have to do it in all your pages):
<%# Register Assembly="MyLibrary" NameSpace="MyLibrary.WebControls" TagPrefix="MyPrefix" %>
And use it like you would use a text box:
<MyPrefix:MyTextBox ID="sampleTextBox" runat="server" />
Personally, I use a set of methods I have developed for bridging the server-side ASP.NET "magic" (I have yet to use the MS MVC stuff yet) and my client-side code because of the munging of the IDs that happens. Here is just one that may or may not prove useful:
public void RegisterControlClientID(Control control)
{
string variableDeclaration = string.Format("var {0} = \"{1}\";", control.ID, control.ClientID);
ClientScript.RegisterClientScriptBlock(GetType(), control.ID, variableDeclaration, true);
}
So, in your server-side code you simply call this and pass in the instance of a control for which you want to use a friendlier name for. In other words, during design time, you may have a textbox with the ID of "m_SomeTextBox" and you want to be able to write your JavaScript using that same name - you would simply call this method in your server-side code:
RegisterControlClientID(m_SomeTextBox);
And then on the client the following is rendered:
var m_SomeTextBox = "ctl00_m_ContentPlaceHolder_m_SomeTextBox";
That way all of your JavaScript code can be fairly ignorant of what ASP.NET decides to name the variable. Granted, there are some caveats to this, such as when you have multiple instances of a control on a page (because of using multiple instances of user controls that all have an instance of m_SomeTextBox within them, for example), but generally this method may be useful for your most basic needs.
What I usually do is create a general function that receives the name of the field. It adds the usual "asp.net" prefix and returns the object.
var elemPrefix = 'ctl00-ContentPlaceHolder-'; //replace the dashes for underscores
var o = function(name)
{
return document.getElementById(elemPrefix + name)
}
With that you can use this kind of calls in jQuery
$(o('buttonId')).bind('click', function() { alert('hi); });
You definitely don't want to hard-code the asp.net-generated ID into your CSS, because it can change if you rearrange things on your page in such a way that your control tree changes.
You're right that CSS IDs have their place, so I would ignore the suggestions to just use classes.
The various javascript hacks described here are overkill for a small problem. So is inheriting from a class and overriding the ID property. And it's certainly not helpful to suggest switching to MVC when all you want to do is refactor some CSS.
Just have separate divs and spans that you target with CSS. Don't target the ASP.NET controls directly if you want to use IDs.
<div id="DataGridContainer">
<asp:datagrid runat=server id="DataGrid" >
......
<asp:datagrid>
</div>
If you're using jQuery then you have loads of CSS selectors and jQuery custome selectors at your disposal to target elements on your page. So rather than picking out a submit button by it's id, you could do something like:
$('fieldset > input[type="submit"]').click(function() {...});
I can see how the .NET system feels less intuitive, but give it a chance. In my experience it actually ends up creating cleaner code. Sure
<asp:button id="ImAButton" runat="server">Click Me</asp:button>
<script type="text/javascript">
var buttonId = <%=ImAButton.ClientId%>
$(buttonId).bind('click', function() { alert('hi); });
</script>
works fine. But this is suffers from not being modular. What you really want is something like this:
<script type="text/javascript">
function MakeAClick(inid)
{
$(inid).bind('click', function() { alert('hi); });
}
</script>
and then later with your code on the java side or the C# side you call MakeAClick. Of course on the C# side it makes more sense, you just ClientID in there.
Maybe this is the real problem with the code you are reviewing.
A much better approach would be to use the ClientIDMode and set it to static. You can even set it for a specific page or globally in the web.config file. Then you never have to deal with this issue again and your JQuery is much cleaner.
Top of page:
<%# Page Title="" ClientIDMode="Static" Language="C#" CodeBehind="..." Inherits="WebApplication1.WebForm2" %>
On control only:
<asp:Panel runat="server" ClientIDMode="Static"></asp:Panel>

Categories