I have a function that returns a snippet of JavaScript and/or HTML.
static public string SpeakEvil()
{
return "<script>alert('BLAH!!');</script>";
}
In the view, Razor is quite rightly HTML encoding it, as most would expect.
#StaticFunctions.SpeakEvil()
How do I have Razor not HTML Encode this, so that the HTML and JavaScript are emitted verbatim, and that any script actually runs?
You could use the Raw() function but it's mostly meant for things that come from the database.
For a helper like you have I would suggest returning an IHtmlString:
static public IHtmlString SpeakEvil() {
return new HtmlString("<script>alert('BLAH!!');</script>");
}
That way you don't have have to call Raw() at every callsite.
Use the Html.Raw helper.
#Html.Raw(StaticFunctions.SpeakEvil())
Return a MvcHtmlString (Inherits from HtmlString) by calling the MvcHtmlString.Create() method like so:
public static MvcHtmlString SpeakEvil()
{
return MvcHtmlString.Create("<script>alert('BLAH!!');</script>");
}
You could also make it into an String extension:
public static MvcHtmlString HtmlSafe(this string content)
{
return MvcHtmlString.Create(content);
}
Source:
http://geekswithblogs.net/shaunxu/archive/2010/04/10/lt-gt-htmlencode-ihtmlstring-and-mvchtmlstring.aspx
Related
I want to create a simple function in a static class ChardinHtml.DataIntro(string message). The function is supposed to render something like data-intro='my message' and I want to use it that way:
<div #ChardinHtml.DataIntro("These are your site's settings")/>.
(The output would be <div data-intro="These are your site's settings"/> )
What exactly should I return?
Is it string/encoded string/MvcHtmlString/MvcHtmlString with encoded string inside? What should I do to protect myself from characters like ( ' ) (apostrophe) inside a message?
The code looks like this:
public static string DataIntro(string msg)
{
string str = string.Format("data-intro='{0}'", msg);
return str;
}
You can create an HTML helper method to render this. You might return MvcHtmlString as the output. Use HttpUtility.HtmlEncode to encode the string before you use it
public static class MyCustomFancyHtmlExtensions
{
public static MvcHtmlString MyFancyAttr(this HtmlHelper helper, string msg)
{
msg = HttpUtility.HtmlEncode(msg);
return new MvcHtmlString(string.Format("data-intro ='{0}'", msg));
}
}
And you can call it like after including the namespace in the razor view using the using statement
#usint YourNamespaceWhereYouDefinedTheMethod
<div class="test" #Html.MyFancyAttr("test'ing")> test</div>
While this answer your question, I am not sure what your use case is, But my recommendation is to write the data attribute directly in the razor view unless you have some complex logic involved in determining what/when to render this.
I have a TreeView, wish is used to display some hierarchy. Also, I have some behaviors implemented, such as if the collapsed nodes will be opened when the parent is checked, or if it's lazy loading or will load everything automatically. But I don't want to let these behaviors hard coded. I want to create a customizable control. Something like Telerik Kendo UI does. They have a control developed, that can be used like this:
#(Html.Kendo().MaskedTextBox()
.Name("phone_number")
.Mask("(999) 000-0000")
.Value("555 123 4567")
)
Notice that you can pass some options to it.
Also, I want to be able to pass the name of the action that will populate my TreeView using async. So, if I use this component at, for example, mysite/myController/indexAction, I want to pass a name of the action who will populate my component asynchronous. Let's exemplify. I want something like this:
#(Html.Foo().HierarchyView()
.Name("myTree")
.AllowCheckBoxes(true)
.PopulateChildrenOnCheck(true)
.Async("GetChildrenAsync")
)
So, I can implement at myController an action
string GetChildrenAsync(int idKey) {
var nodes = new List<HierarchViewNodes>();
(...) //implementation to populate the children nodes
return JsonConvert.SerializeObject(nodes);
}
So, it would be an start for my customizable control. Of course I can extend it a lot.
I've searched and learned about RenderPartial and RenderAction, but I can't figure out yet how I can fully use it to make really reusable controls like the one I explained.
You might want to take a look at making some custom HTML helpers. For example, yours might look something like this:
public static MvcHtmlString MyTreeView(this HtmlHelper html, params...){
var myHtmlContent = ....;
// .. implement your functionality and generate the html to put in your view
return MvcHtmlString.Create(myHtmlContent);
}
and you could use it in your Razor view like this:
<div>#Html.MyTreeView(params...)</div>
That is a very simple example, but hopefully it puts you on the right track.
I'd suggest some HTML extensions, as rwisch45 said, but protected (and organized) within a separate "sub-helper", like Kendo and DevExpress:
public static class HtmlExtensions
{
public static static MyCustomHelper CustomHelper(this HtmlHelper htmlHelper)
{
return new MyCustomHelper(htmlHelper);
}
}
public class MyCustomHelper
{
HtmlHelper _HtmlHelper;
public MyCustomHelper(HtmlHelper htmlHelper) { _HtmlHelper = htmlHelper; }
public MvcHtmlString WriteSomethingInteresting(string value)
{ return new MvcHtmlString(value); }
public MyCustomGrid CreateMyGrid(object gridOptions)
{
// I won't show now how to transform dynamic into type.
// You can find that on SO quite easy.
var typedOptions = TransformDynamicIntoClass<GridOptions>(gridOptions);
return new MyCustomGrid(typedOptions);
}
}
public class MyCustomGrid : IHtmlString
{
public string ToHtmlString()
{
// Return your grid as an HTML object!
}
}
This way you'll have:
#Html.CustomHelper().MyCustomGrid(new { Option1 = "", Option2 = "", ...... });
You may, however, play a little with IDisposable, to have something like:
#using(Html.CustomHelper().MyCustomGrid(....))
{
// Dunno what could come here for a grid (poor sample) but maybe for a pane helper?
}
I want to create a htmlhelper method in an MVC4 project using Entity Framework 5.0
For one of my pages, descriptions are loaded. Most descriptions are:
description description description
but some are
"description description description"
Now how do I write a htmlhelper method that removes these " " quotes?
Below is an example of an already working htmlhelper method that adds three dots for descriptions that are too long:
public static class HtmlHelpers
{
public static string Truncate(this HtmlHelper helper, string input, int length)
{
if(input.Length <= length)
{
return input;
}
else
{
return input.Substring(0,length) + "...";
}
}
So I basically need something like above but with the purpose of not displaying " " quotes
You can use the String.Trim(Char[]) (MSDN) method to get rid of the leading and trailing double quotes in a string.
string foo = "\"This is a quoted string\"".Trim('"');
Then you don't really need an HTML helper you can just use Trim() directly in your view.
#Model.Description.Trim('"')
Or make it a property of your model :
public string DescriptionWithoutQuotes
{
get { return this.Description.Trim('"'); }
}
Using a HTML helper for this would be overkill, in my opinion.
Try this:
public static string Unquote(this HtmlHelper helper, string input)
{
if (string.IsNullOrWhiteSpace(input))
return string.Empty;
return input.Replace("\"", "");
}
I've got a ASP.NET MVC 3 Razor Web Application.
I've got a WebViewPage extension:
public static bool Blah(this WebViewPage webViewPage)
{
return blah && blah;
}
And i want to access this from my HtmlHelper extension:
public static MvcHtmlString BlahHelper(this HtmlHelper htmlHelper, string linkText, string actionName)
{
// how can i get access to the WebViewPage extension method here?
}
I can of course duplicate the functionality of the WebViewPage extension if i had to, but just wondering if it's possible to access it from the HTML helper.
// Warning: this cast will crash
// if you are not using the Razor view engine
var wvp = (WebViewPage)htmlHelper.ViewDataContainer;
var result = wvp.Blah();
You should change that method to extend HttpContextBase, which you can access from both HtmlHelper and WebViewPage.
I would try:
((WebViewPage)htmlHelper.ViewContext.View). Blah()
I had the same problem and the accepted answer led me to the solution (+1). Maybe this hint helps somebody else too.
Additionally I had to use the generic version of WebViewPage inside a strongly type view.
Otherwise I got a type cast exception.
public static MvcHtmlString ToBodyEnd<TModel>(this HtmlHelper<TModel> htmlHelper, ...) {
var vp = (DerivedWebViewPage<TModel>)htmlHelper.ViewDataContainer;
//... more code ...
}
I'm writing an ASP.NET MVC Html Helper which basically takes 2 HTML Helpers that return IHtmlStrings and combines them together and also returns them as an IHtmlString like so:
//this doesn't work
public static IHtmlString CompositeHelper(this HtmlHelper helper, string data)
{
//GetOutput returns an IHtmlString
var output1 = new Component1(data).GetOutput();
var output2 = new Component2(data).GetOutput();
return output1 + output2
}
Now I know this isn't going to work because IHtmlString is an interface with an implementation that is a complex type, but if I go
return output1.ToHtmlString() + output2.ToHtmlString()
I just get a normal string which gets HtmlEncoded when I return it from my HtmlHelper.
So my question is, how can I take the output form two IHtmlStrings and combine them into a single IHtmlString?
Like this:
return new HtmlString(output1.ToString() + output2.ToString());