views:

217

answers:

3

As ScottGu says in his blog post «by default content emitted using a @ block is automatically HTML encoded to better protect against XSS attack scenarios». My question is: how can you output a non-HTML-encoded string?

For the sake of simplicity, pls stick to this simple case:

@{
 var html = "<a href='#'>Click me</a>"
 // I want to emit the previous string as pure HTML code...
}

Thanks

+3  A: 

You can create a new instance of MvcHtmlString which won't get HTML encoded.

@{
  var html = MvcHtmlString.Create("<a href='#'>Click me</a>")
}

Hopefully there will be an easier way in the future of Razor.

If you're not using MVC, you can try this:

@{
  var html = new HtmlString("<a href='#'>Click me</a>")
}
Manticore
Actually you sould be able to use `new HtmlString()` in MVC 3 as well since that type is .NET 4.
marcind
Indeed! However when typing all that in one expression I like the MVC one more. E.g. @MvcHtmlString.Create(myString). Personal preference!
Manticore
+3  A: 

new HtmlString is definitely the answer.

We looked into some other razor syntax changes, but ultimately none of them ended up really being any shorter than new HtmlString.

We may, however, wrap that up into a helper. Possibly...

@Html.Literal("<p>something</p>")

or

@"<p>something</p>".AsHtml()
Erik Porter
Would it be possible to add @=myString as a way to output HTML? Maybe too much of a flashback to WebForms...
Manticore
We want to avoid adding syntax constructs where they don't cover a major user case. Most of the time, you'll be using helper methods to build strings and IHtmlString works perfectly there. For the odd cases where you need to output a literal string without a helper, we can provide a method for you: @Literal(foo) or similar.
anurse
A: 

I ran into this problem as well when transitioning our project to the new Razor view engine. The approach I took was slightly different because we had to generate JSON data from C# and wanted to output it upon page load.

What I eventually did was to implement a RawView that was a parallel of View inside of the cshtml files. Essentially, to get a raw string,

@(new HtmlString(View.Foo))

// became
@RawView.Foo

This requires a few changes to the project layout, so I just wrote up a blog post about it here. In short, this required a duplicate implementation of MVC's DynamicViewDataDictionary and a new WebViewPage that contains the RawView. I also went ahead and implemented the index operator on the RawView to allow for

@RawView["Foo"]

In the off-chance that someone needs to loop over the data with a list of keys.

Reading anurse's comment, it probably would have been better off if I had named this as a Literal instead of RawView.

Anh-Kiet Ngo