Writing/outputting HTML strings unescaped - asp.net-mvc

I've got safe/sanitized HTML saved in a DB table.
How can I have this HTML content written out in a Razor view?
It always escapes characters like < and ampersands to &.

Supposing your content is inside a string named mystring...
You can use:
#Html.Raw(mystring)
Alternatively you can convert your string to HtmlString or any other type that implements IHtmlString in model or directly inline and use regular #:
#{ var myHtmlString = new HtmlString(mystring);}
#myHtmlString

In ASP.NET MVC 3 You should do something like this:
// Say you have a bit of HTML like this in your controller:
ViewBag.Stuff = "<li>Menu</li>"
// Then you can do this in your view:
#MvcHtmlString.Create(ViewBag.Stuff)

You can use
#{ WriteLiteral("html string"); }

Sometimes it can be tricky to use raw html. Mostly because of XSS vulnerability. If that is a concern, but you still want to use raw html, you can encode the scary parts.
#Html.Raw("(<b>" + Html.Encode("<script>console.log('insert')</script>" + "Hello") + "</b>)")
Results in
(<b><script>console.log('insert')</script>Hello</b>)

You can put your string into viewdata in controller like this :
ViewData["string"] = DBstring;
And then call that viewdata in view like this :
#Html.Raw(ViewData["string"].ToString())

Apart from using #MvcHtmlString.Create(ViewBag.Stuff)
as suggested by Dommer, I suggest you to also use AntiXSS library as suggested phill http://haacked.com/archive/2010/04/06/using-antixss-as-the-default-encoder-for-asp-net.aspx
It encodes almost all the possible XSS attack string.

Complete example for using template functions in RazorEngine (for email generation, for example):
#model SomeModel
#{
Func<PropertyChangeInfo, object> PropInfo =
#<tr class="property">
<td>
#item.PropertyName
</td>
<td class="value">
<small class="old">#item.OldValue</small>
<small class="new">#item.CurrentValue</small>
</td>
</tr>;
}
<body>
#{ WriteLiteral(PropInfo(new PropertyChangeInfo("p1", #Model.Id, 2)).ToString()); }
</body>

Related

ASP.Net C# Razor showing encoded HTML instead of raw html

I'm using the JQM-DateBox - which needs the following Razor markup:
#Html.TextBoxFor(m => m.From, new { #name = "mydate", #id = "mydate",
#data_role = "datebox",
#data_options = "{'mode':'flipbox', 'dateFormat':'dd/mm/YYYY' ,'useNewStyle':true} ")
However, this renders as:
<input data-options=" {'mode':'flipbox', 'dateFormat':'dd/mm/YYYY' ,'useNewStyle':true} "
data-role="datebox" id="mydate"
name="From" type="text" value="29/08/2013 00:00:00" />
I know you can use html.raw - but how do you use it within a helper?
I need to show:
{'mode':
...instead of...
{'mode':
Try #Html.Raw(HttpUtility.HtmlDecode(#Html.TextBoxFor(...).ToHtmlString())).
TextBoxFor uses TagBuilder which is ultimately responsible for turning ' in to ' (since it uses MergeAttributes with the htmlAttributes parameter passed to the helper).
Instead of pasting the answer, check out Stop the tag builder escaping single quotes ASP.NET MVC 2
Also, this isn't quite the same exact question, but then it is. I'll leave it up to others if they want to close it and cite the above reference.

Mvc Html.Label or Html.TextBox doesn't create

I'm making a test page for a project I'm working on and I've made desired progress so far but I'm trying to create TextBoxes from a model of List being passed to the view, however, the it seems to just ignore anything I have tried.
<form id="form1" runat="server">
<input id="btnsubmit" type="submit" name="Submit" onclick="Submit" />
<div id="divControls">
<% foreach (TextBox control in (this.Model as List<TextBox>))
{
Html.Label("lblLabel", control.Text);
Html.TextBox(control.ID, control.Text, new { id = control.ID, style = "width:50", name = "txt" + control.ID });
} %>
</div>
</form>
The List isn't null in the Controller on return. I don't have a clue at what the problem could be. If I throw a Something in the for loop it executes the appropriate number of times so why isn't it creating the labels or textboxes?
At first I thought it was that I'm adding them inside a form but I removed the form tags and it still didn't work so I really have no Idea, any help would be much appreciated. I'm relatively new to MVC.
[HttpPost]
public ActionResult Index(FormCollection form)
{
List<TextBox> controls = new List<TextBox>();
foreach (String Key in form.Keys)
{
if (Key.Contains("txt"))
{
TextBox textBox = new TextBox();
textBox.ID = Key;
textBox.Text = form.GetValues(Key)[0];
controls.Add(textBox);
}
}
return View("Index", controls);
}
Here's my Action encase it's helps.
Also encase I wasn't clear enough, I am adding controls to a form at runtime using JQuery and then that Action will be part of the submit so it must send the textboxes back to the view so they are not deleted.
Like I said I'm new to the whole MVC and Asynchronous thing so If there's a better way to do this, advice would be much appreciated.
Your not printing the html
<% foreach (TextBox control in (this.Model as List<TextBox>))
{%>
<%=Html.Label("lblLabel", control.Text)%>
<%=Html.TextBox(control.ID, control.Text, new { id = control.ID, style = "width:50", name = "txt" + control.ID })%>
<% } %>
Your code is looping through the controls and the Html.whaterever is returning a string but your not doing anything with it, just discarding it.
you also don't need to return a whole TextBox object. This is probably inefficient. Just return an struct or a class containing your data
Html.Label returns a string containing a <label> tag.
You're discarding that string.
You need to write it to the page by writing <%= Html.Whatever() %>.

ASP.NET MVC 3 - Add/Remove from Collection Before Posting

I have a model that contains a collection, such as this:
class MyModel
{
public List<MySubModel> SubModels { get; set; }
}
In the view, I want to dynamically add/remove from this list using Javascript before submitting. Right now I have this:
$("#new-submodel").click(function () {
var i = $("#submodels").children().size();
var html = '<div>\
<label for="SubModels[' + i + '].SomeProperty">SomeProperty</label>\
<input name="SubModels[' + i + '].SomeProperty" type="textbox" />\
</div>'
$("#submodels").append(html);
});
This works, but it's ugly. And, if I want to show those labels/textboxes for the existing items, there's no clean way to do that either (without duplicating).
I feel like I should be able to use Razor helpers or something to do this. Any ideas? Help me stay DRY.
You approach may lead to unexpected errors if you when you are removing or adding the divs. For example you have 4 items, you remove the first item, then $('#submodels').children().size() will return 3, but your last inserted div has the name attribute value set SubModels[3].SomeProperty which results in a conflict. And if your posted values contain SubModels[1] but not SubModels[0] the default model binder will fail to bind the list (it will bind it as null). I had to learn this the hard way...
To eliminate the aforementioned problem (and your's) I suggest you do something like this:
$("#addBtn").click(function() {
var html = '<div class="submodel">\
<label>SomeProperty</label>\
<input type="textbox" />\
</div>'; // you can convert this to a html helper!
$("#submodels").append(html);
refreshNames(); // trigger after html is inserted
});
$(refreshNames); // trigger on document ready, so the submodels generated by the server get inserted!
function refreshNames() {
$("#submodels").find(".submodel").each(function(i) {
$(this).find("label").attr('for', 'SubModels[' + i + '].SomeProperty');
$(this).find("label").attr('input', 'SubModels[' + i + '].SomeProperty');
});
}
Then your view (or even better an EditorTemplate for the SubModel type) can also generate code like:
<div class="submodel">
#Html.LabelFor(x => x.SomeProperty);
#Html.EditorFor(x => x.SomeProperty);
</div>
It would also be possible to convert the code generation to a html helper class, and use it in the EditorTemplate and in the JavaScript code
I would recommend you going through the following blog post.

Passing NewLine (or <Br />) inside ViewData["msg"]

How do I pass an Environment.NewLine (or a < br />) inside a ViewData["msg"]
that renders as a real <br /> inside the View itself?
I'm using C# ...
You can simply use
HttpUtility.HtmlEncode("<br />");
Have a look here for further details.
EDIT:
I am sorry but I did not understand the question at the beginning. I thought you wanted to encode the passed string. Sometimes I read question too fast :)
Anyway to completely answer your question have a look at these samples. Suppose in your action you have:
[HttpGet]
public virtual ActionResult Index() {
ViewData["Message"] = "This is a test." + "<br />" + "Does it work?";
return View();
}
And in your view you have
<p>Sample 1: <br /><%= ViewData["Message"]%></p>
<p>Sample 2: <br /><%: ViewData["Message"]%></p>
Notice the difference between the two construct. You will get the following results:
Sample 1:
This is a test.
Does it work?
Sample 2:
This is a test.<br />Does it work?
So the first sample usage answer your question. The key is to simply not encoding the string as opposed to what I understood at the beginning. The second construct, the one that use <%: %>, available if you're using .NET 4.0, automatically encode every string it render.
If you still want to use this latest construct and avoid that the string would be encoded you have to use a trick. Simply tell the construct that the string is already encoded and it does not need to be re-encoded. To achieve this use this sample code
[HttpGet]
public virtual ActionResult Index() {
ViewData["Message2"] = MvcHtmlString.Create( "This is a test." + "<br />" + "Does it work?" );
return View();
}
and in the view normally use the <%: %> construct
<p>Sample 3: <br /><%: ViewData["Message2"]%></p>
For more details on using the MvcHtmlString and how it works please refer to this question on SO.
Ciao!
Did you try \n or \r inside the ViewData string itself?
Use this:
TempData["MsgString"] = MvcHtmlString.Create("No Data" + "<br />" + "For Something");
Or, with variables:
TempData["MsgString"] = MvcHtmlString.Create(Strings.StrNoData + "<br />" + Strings.StrSomething);

.NET MVC View question

I have this cute little progress bar looking thing in a dashboard page. Once it is started up, it updates itself every minute via ajax, javascript, blah, blah. Since some of my viewers are looking at it on older Blackberries, I normally figure out how big the bar should be for the initial rendering server-side, and draw the page accordingly, then let the javascript take over after that, on those viewers that have it.
The old code, plain old ASP.NET has an asp:Label in the page where the img tag goes, and on the server I cat together the whole thing. As I refactor to an MVC way of looking at things, I thought how wonderful it would be to only write the width style attribute of the image on the server. The code on the page would be a good deal more understandable that way.
But it doesn't work. Example:
<img src="/content/images/blue_1px.png" class="productionBar_variableBar"
style="width: <% =dbd["ThisShiftProduction_variableBar"] %>;"/>
Unfortunately, Visual Studio doesn't seem to recognize the <% %> escape inside of the quoted style attribute.
Any suggestions?
Siggy
The simplest way - creating HtmlHelper extension:
public static class Html
{
public static string ProgressBar(this HtmlHelper html, int width)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("img src=\"/content/images/blue_1px.png\" class=\"productionBar_variableBar\" style=\"width: {0};\" />", width);
return sb.ToString();
}
// OR
public static string ProgressBar(this HtmlHelper html, int width, string src, string cssClass)
{
TagBuilder tagBuilder = new TagBuilder("img");
tagBuilder.AddCssClass(cssClass);
tagBuilder.MergeAttribute("style", "width: " + width.ToString());
string srcUrl = new UrlHelper(html.ViewContext.RequestContext).Content(src);
tagBuilder.MergeAttribute("src", srcUrl);
return tagBuilder.ToString(TagRenderMode.Normal);
}
}
Using it:
<%= Html.ProgressBar(dbd["ThisShiftProduction_variableBar"]) %>
<!-- OR -->
<%= Html.ProgressBar(dbd["ThisShiftProduction_variableBar"], "~/content/images/blue_1px.png", "productionBar_variableBar") %>
Have you tried doing this instead
<img src="/content/images/blue_1px.png" class="productionBar_variableBar" style='width: <% =dbd["ThisShiftProduction_variableBar"] %>;'/>
Notice the single quotes instead of the double quotes in the style attribute

Resources