ASP.NET MVC razor: conditional attribute in HTML

The code below does not seem clean. Any suggestion to improve the code?

<li @if(ViewData["pagename"].ToString()=="Business details"){ <text>class="active" </text> } > <a @if(ViewData["pagename"].ToString()=="Business details"){ <text>style="color: white; background-color: #08C; border: 1px solid #08C;" </text> } href="@Url.Action("BusinessDetails", "Business")">Business Details</a> </li> <li @if (ViewData["pagename"].ToString() == "Booking policies"){ <text>class="active"</text> }> <a @if (ViewData["pagename"].ToString() == "Booking policies") { <text>style="color: white; background-color: #08C; border: 1px solid #08C;" </text> } href="@Url.Action("BookingPolicies", "Business")">Booking policies</a> </li> 
+67
asp.net-mvc asp.net-mvc-3 razor
Feb 22 '12 at 17:07
source share
6 answers

MVC has built-in conditional attributes ...

 <div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div> <div class="@myClass">Content</div> 

If @myClass is zero, it just won't use the attribute at all ...

I know that this may not completely solve your current problem, but it deserves attention!

http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx

+114
Feb 22 '12 at 17:20
source share
 <li class="@(ViewBag.pagename == "Business details" ? "active" : null)"> 

You must replace inline style="..." separate class name and use the same syntax there.

However, it would be easier to make a separate extension method for the HTML helper, which will take the name of the page and action and generate HTML in general.

+65
Feb 22 '12 at 17:10
source share

I use a small helper method that will conditionally add an attribute if the value is not empty, and if defined, when the expression of a Boolean function evaluates to true :

 public static MvcHtmlString Attr(this HtmlHelper helper, string name, string value, Func<bool> condition = null) { if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) { return MvcHtmlString.Empty; } var render = condition != null ? condition() : true; return render ? new MvcHtmlString(string.Format("{0}=\"{1}\"", name, HttpUtility.HtmlAttributeEncode(value))) : MvcHtmlString.Empty; } 

Once defined, I can use this method in my Razor views:

 <li @(Html.Attr("class", "new", () => example.isNew))> ... </li> 

The above code will display <li class="new">...</li> if example.isNew == true , if you do not omit the entire class attribute.

+19
Apr 09 '14 at 20:30
source share

In MVC4

 <!DOCTYPE html> <html> <head> </head> <body> @{ string css = "myDiv"; } <div class='@css'></div> </body> </html> 

or

 <!DOCTYPE html> <html> <head> </head> <body> @{ string css = "class=myDiv"; } <div @css></div> </body> </html> 

More details here: http://evolpin.wordpress.com/2012/05/20/mvc-4-code-enhancements/

+3
Jan 30 '13 at 11:27
source share

Approach using the TagWrap extension method. The code for your question will look like this:

 @using (Html.TagWrap("li", condition ? new { @class = "active" } : null)) { var anchorAttrs = new Dictionary<string, object> { { "href", Url.Action("BusinessDetails", "Business") } }; if(condition) { anchorAttrs["style"] = "color: white; background-color: #08C; border: 1px solid #08C;"; } using (Html.TagWrap("a", anchorAttrs)) { <text>Business Details</text> } } 

TagWrap Extension Methods

Using Microsoft.AspNetCore.Mvc.ViewFeatures

 public static IDisposable TagWrap(this IHtmlHelper htmlHelper, string tagName, object data) { return htmlHelper.TagWrap(tagName, HtmlHelper.AnonymousObjectToHtmlAttributes(data)); } public static IDisposable TagWrap(this IHtmlHelper htmlHelper, string tagName, IDictionary<string, object> data) { var tag = new TagBuilder(tagName); tag.MergeAttributes(data); htmlHelper.ViewContext.Writer.Write(tag.RenderStartTag()); return new DisposableAction(() => htmlHelper.ViewContext.Writer.Write(tag.RenderEndTag())); } 

Helper class used to render the closing tag on Dispose

 public class DisposableAction : IDisposable { private readonly Action DisposeAction; public DisposableAction(Action action) { DisposeAction = action; } public void Dispose() { DisposeAction(); } } 
0
Jul 10 '18 at 6:31
source share

Based on the defrosts, respond here to the adaptation by taking object instead of string :

  public static MvcHtmlString ConditionalAttr(this HtmlHelper helper, string attributeName, object value, Func<bool> condition) { if (string.IsNullOrEmpty(attributeName) || value == null) { return MvcHtmlString.Empty; } var render = condition != null ? condition() : true; return render ? new MvcHtmlString($"{attributeName}=\"{HttpUtility.HtmlAttributeEncode(value.ToString())}\"") : MvcHtmlString.Empty; } 

This way you do not need to turn other data types into strings before passing them, while preserving fiew .ToString .ToString() . There is a difference : traversing an empty line will still be displayed. As an example:

 @Html.ConditionalAttr("data-foo", "", () => Model.IsFooNeeded) // Ouput: data-foo="" 
0
May 7 '19 at 5:29
source share



All Articles