HTML.Encode but preserve line breaks - asp.net-mvc

I take user input into a text area, store it and eventually display it back to the user.
In my View (Razor) I want to do something like this...
#Message.Replace("\n", "</br>")
This doesn't work because Razor Html Encodes by default. This is great but I want my line breaks.
If I do this I get opened up to XSS problems.
#Html.Raw(Message.Replace("\n", "</br>"))
What's the right way to handle this situation?

Use HttpUtility.HtmlEncode then do the replace.
#Html.Raw(HttpUtility.HtmlEncode(Message).Replace("\n", "<br/>"))

If you find yourself using this more than once it may be helpful to wrap it in a custom HtmlHelper like this:
namespace Helpers
{
public static class ExtensionMethods
{
public static IHtmlString PreserveNewLines(this HtmlHelper htmlHelper, string message)
{
return message == null ? null : htmlHelper.Raw(htmlHelper.Encode(message).Replace("\n", "<br/>"));
}
}
}
You'll then be able to use your custom HtmlHelper like this:
#Html.PreserveNewLines(Message)
Keep in mind that you'll need to add a using to your Helpers namespace for the HtmlHelper to be available.

You can encode your message, then display it raw. Something like:
#Html.Raw(Server.HtmlEncode(Message).Replace("\n", "<br/>"))

For those who use AntiXssEncoder.HtmlEncode
As AntiXssEncoder.HtmlEncode encode the /r/n character to
so the statement should be
_mDraftMsgModel.wnItem.Description = AntiXssEncoder.HtmlEncode(draftModel.txtMsgContent, false).Replace("
", "<br/>");

In my case, my string contained html that I wanted to encode but I also wanted the HTML line breaks to remain in place. The code below turns the HTML line breaks in to \n then encodes everything. It then turns all instances of \n back in to HTML line breaks:
#Html.Raw(HttpUtility.HtmlEncode(message.Replace("<br/>", "\n").Replace("<br />", "\n")).Replace("\n", "<br/>"))

Related

#Helper razor enconding html

According to https://blog.cindypotvin.com/character-encodings-with-razor-helpers/ and some other resources #Helper blocks return a HelperResult class that Implements IHtmlString.
Being and HtmlString all the string inside the #helper blocks should not be encoded.
But I have the following scenario (the real scenario is more complex) where the html is encoded
#helper Test(){
#(new HtmlString("<label>Test 1</label>"))
#(new HtmlString("<label>Test 2</label>"))
}
When I check the view in browser I see literally <label> Test 1 .... because the Html code generate inside the #helper Test is between quotes.
But adding a RawString then it works correctly.
#helper Test(){
#(new RawString(new HtmlString("<label>Test 1</label>").ToString()))
#(new RawString(new HtmlString("<label>Test 2</label>").ToString()))
}
Taking into account that HtmlString it´s for Razor to not encode a string and #Helper returns HtmlString, I don´t get why I need to add RawString to render correctly the html code on browser.
This looks like a matter of incorrect expectations and/or interpretations...
A #helper method renders its output to an output stream, resulting in a plain text string. That string may contain HTML, and if so, then that HTML may or may not have been HTML encoded along the way (depending on how the helper was written). The resulting plain text string is then returned inside an IHtmlString wrapper object.
If an IHtmlString object is rendered using #(...), to Razor this means 'don't HTML-encode this, that was done already if/when/where needed'.
In short, doing #Test() sends the exact string content without further encoding to the browser (which then interprets it). If your aim was to encode it, then you could use #(Test().ToString()) because that pulls the string out of its IHtmlString protective cover, and then it will be HTML-Encoded.
If you inspect Test().ToString() then you can see the plain-text content, which for your Test() will look like "<label>...</label><label>...</label>". There's not a trace of the original HtmlString objects that you used, they were all rendered, and nothing was HTML-Encoded because you used #(new HtmlString(...)) for each.
It may be worth noting that these three #helper methods all have exactly the same output (except perhaps for some whitespace):
#helper Test()
{
<label>Test</label>
}
#helper Test()
{
#(new HtmlString("<label>Test</label>"))
}
#helper Test()
{
#(Html.Raw("<label>Test</label>"))
}
The result for all of these is the plain string "<label>Test</label>" wrapped as an IHtmlString.
Finally, if you would WANT the <label> to be HTML-Encoded, then this is what you'd need to use:
#helper Test()
{
#("<label>Test</label>")
}
The result of this is the plain string "<label>Test</label>" wrapped as an IHtmlString.

How to setup a helper for an Html extension

I apologize for the somewhat vagueness of this question in advance. I have setup a number of custom Html helpers to use in partial views...
What i am trying to do is set it up so if want to change how the field is displayed, then I can use an extension.
The following:
#Html.FieldFor("Somefield", "Label name:", #Model.Somevalue)
will render a standard text box on the screen with with the Id of "SomeField" and a Label of "Label Name:" and the third element is what would be shown in the field itself.
Let's say I want to show the Value in #Model.Somevalue on the screen without it being in a text field if the value is not editable at that time...
In that case I would like to be able to have something like this...
#Html.FieldFor("Somefield", "Label name:", #Model.Somevalue).NotEditbable()
and use that in the helper to determine the code that is passed back. Can someone point me to a tutorial or other resource I can use to accomplish this?
below is the Helper in question if that is useful...
public static MvcHtmlString FieldFor(this HtmlHelper helper, string FieldName, string Label, string ValueContents = null)
{
return new MvcHtmlString(String.Format("<label for=\"{0}\">{1}</label><input id=\"{0}\" type=\"text\" Value = \"{2}\">", FieldName, Label, ValueContents));
}
I ended up using this page as a guide to setup a new extension method and then to create the method I switched the MVCHtmlString to a regular string... Made the alterations, I wanted to make and then re-encoded it to a MVCHtmlString...

ASP.NET MVC with Razor, custom HtmlHelper outputs just text

I am experimenting with custom HtmlHelpers, but can't get even a basic one to work correctly. My code (just for testing sake) looks like this -
My class -
namespace HtmlHelpers.Extensions
{
public static class Helpers
{
public static string MySubmitButton(this HtmlHelper helper)
{
return String.Format("<input type=\"submit\" value=\"Submit This\">");
}
}
}
In my view -
#using HtmlHelpers.Extensions;
#Html.MySubmitButton()
This I believe should generate a simple submit button, but instead, it justs writes the following text to the screen -
<input type="submit" value="Submit">
I inspected the element, and for some reason the entire input element is being surrounded with double quotes.
Anyone know why? Thanks!
I believe you should be returning a MvcHtmlString class. Try
public static MvcHtmlString MySubmitButton(this HtmlHelper helper)
{
return MvcHtmlString.Create("<input type=\"submit\" value=\"Submit This\">");
}
although there's probably better ways to do this using a TagBuilder if you look at examples online, or the MVC source code since it's open source, you can look at their html helpers(although they are pretty complicated due to the way they layer them).
To directly answer your question of "why" it was displaying that as if it were a string, is Razor tries to be safe and convert anything you display as text instead of HTML/script. For example, #Model.PeronName will escape any characters in the peron's name with HTML character codes. Consider if there was no protection like this, and one of your users changed their name to be <script>someDangerousJavascriptThatWouldChangeCurrentUsersPassword()</script>, then posted on your forum or anywhere their name would appear, then other users visit the page, and that javascript runs and POSTS a change password form for that current user's password to some password that the hacker chose in the script. There are a wide variety of complicated attacks like this, or users might accidentally enter angle brackets(and while fairly harmless if treated as HTML they will mess up your page display).
For that reason MVC will assume just about any string is not HTML and thus replace things like <script> with <script> which basically is a way of saying "this is not html/script, I want you to display the less-than symbol and greater than symbol". If you wanted to display something as HTML, there is a #Html.Raw() helper for that, and it won't clean output, and thus should never be used with a string that you concatenated together from any data that a user my supply.

Passing #Url.Content as parameter in ASP MVC

I am building a custom control in ASP MVC using razor generator. It will take an image as parameter. I want to be able to make the method call in my view like this
#Html.MyMethod(#Url.Content("~/Content/images/photo1.jpg"))
I want to know what is the type of the #Url.Content so that I can declare it in the definition of MyMethod.
Thanks.
You don't need a second # here. Return type of Url.Content is System.String.
MyMethod can take a string as Content returns a string:
public static IHtmlString MyMethod(this HtmlHelper helper, string url)
{
return new MvcHtmlString("<img src=\"" + url + "\" />");
}
Also, you won't need the # operator:
#Html.MyMethod(Url.Content("~/Content/images/photo1.jpg"))

Create an ActionLink with HTML elements in the link text

In an ASP.NET MVC view I'd like to include a link of the form:
Link text <span>with further descriptive text</span>
Trying to include the <span> element in the linkText field of a call to Html.ActionLink() ends up with it being encoded (as would be expected).
Are there any recommended ways of achieving this?
You could use Url.Action to build the link for you:
link text <span>with further blablah</span>
or use Html.BuildUrlFromExpression:
text <span>text</span>
if you like using Razor, this should work:
link text <span>with further blablah</span>
Another option is to render your action link to an MvcHtmlString as per normal, using either HTML.ActionLink, or Ajax.ActionLink (depending on your context), then write a class that takes the rendered MvcHtmlString and hacks your html link text directly into the already rendered MvcHtmlString, and returns another MvcHtmlString.
So this is the class that does that: [please note that the insertion/substitution code is VERY simple, and you may need to beef it up to handle more nested html]
namespace Bonk.Framework
{
public class CustomHTML
{
static public MvcHtmlString AddLinkText(MvcHtmlString htmlString, string linkText)
{
string raw = htmlString.ToString();
string left = raw.Substring(0, raw.IndexOf(">") + 1);
string right = raw.Substring(raw.LastIndexOf("<"));
string composed = left + linkText + right;
return new MvcHtmlString(composed);
}
}
}
And then you would use it in the view like this:
#Bonk.Framework.CustomHTML.AddLinkText(Ajax.ActionLink("text to be replaced", "DeleteNotificationCorporateRecipient"), #"Link text <span>with further descriptive text</span>")
This approach has the advantage of not having to reproduce/understand the tag-rendering process.

Resources