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("\"", "");
}
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.
Is there a way to do something like the following:
public static IHtmlString TableFor(this HtmlHelper helper, IEnumerable<MaterialGroup> groups, Func<HtmlHelper, MaterialGroup, int, string> tableContentsFunc)
{
return MvcHtmlString.Create("#Html.TextBoxFor(x => this.Model.Something)");
}
Obviously this is a trivial example, but when ever I try something of the sort it renders the Helpers i.e. "#Html.TextBoxFor(x => this.Model.Something)" as text on the page instead of processing them as helpers.
Is there a way to achieve this?
public static MvcHtmlString TableFor(this HtmlHelper<IEnumerable<MaterialGroup>> helper, IEnumerable<MaterialGroup> groups, Func<HtmlHelper<MaterialGroup>, MaterialGroup, int, string> tableContentsFunc)
{
String html = "<table class='materials joists'>";
String endHtml = "</table>";
for (int i = 0; i < groups.Count(); ++i)
{
HtmlHelper<MaterialGroup> groupHelper = new HtmlHelper<MaterialGroup>(helper.ViewContext, helper.ViewDataContainer); // Crashes here with cannot convert IEnumerable<MaterialGroup> to MaterialGroup.
html += TbodyFor(groupHelper , groups.ElementAt(i), i);
html += tableContentsFunc(groupHelper , groups.ElementAt(i), i);
}
return MvcHtmlString.Create(html + endHtml);
}
public static string TbodyForJoists(this HtmlHelper<MaterialGroup> helper, MaterialGroup group, int index)
{
string html = string.Empty;
MvcHtmlString markTextbox = InputExtensions.TextBoxFor<MaterialGroup, String>(helper, x => group.Joists.ElementAt(i).Mark, new { Name = "MaterialGroups[" + index + "].Joists[" + i + "].Mark", Class = "auto-size first-column" });
html += martTextbox;
.
.
.
return html;
}
When I attempt the above I get issues with the HtmlHelper<> Types.
If I leave it with just HtmlHelper I get an error telling me to explicity state since it doesn't know what I doing with it. If I explicitly state is have conversion? issues I guess you could say.
How can I simply just use the TextBoxFor in this way?
Because that is very literally what you are telling it to do. The output of the helper itself is not processed by Razor. Whatever you return is what's going on the page.
However, you could always do:
MvcHtmlString textBox = Html.TextBoxFor(expression);
And, you'd have to feed the helper the expression to use. It perhaps would be easier in this situation to use Html.TextBox instead, but then you're going to have to do more work to try to figure out the right names and such for the fields.
It's going to be far easier and less convoluted to just use editor templates for this type of thing.
I try to rewrite and customize #Html.ActionLink, in one of overloads of this method the parameters are:
public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper,
string linkText, string actionName);
And I want something like the above and also need to find AreaName and ControllerName without pass it by parameters, I think to use the followings:
string controller = ViewContext.RouteData.Values["Controller"];
string area = ViewContext.RouteData.DataTokens["Area"];
but the error rise as :
An object reference is required for the non-static field, method, or property
'System.Web.Mvc.ControllerContext.RouteData.get'
And obviously I use static, so what is your suggestion to find Area Name and Controller Name in HtmlHelpers ?
Use this:
string controllerName =
(string)htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
string areaName =
(string)htmlHelper.ViewContext.RouteData.DataTokens["area"];
public static MvcHtmlString ActionLink(
this HtmlHelper htmlHelper,
string linkText,
string actionName
)
{
RouteData rd = htmlHelper.ViewContext.RouteData;
string currentController = rd.GetRequiredString("controller");
string currentAction = rd.GetRequiredString("action");
// the area is an optional value and it won't be present
// if the current request is not inside an area =>
// you need to check if it is null or empty before using it
string area = rd.Values["area"] as string;
...
}
I believe "controller" and "area" should be lower case. Here is how to get the area value:
ASP.NET MVC - Get Current Area Name in View or Controller
If not currently in an area it would give a object reference exception, so check for null first and then set the value if it is not null. Your controller is also correct, just try it in lower case. Hope this helps
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
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());