Reputation: 77329
My ASP.NET MVC view is getting "cluttered up" because often times I need to conditionally show things which leads to long inline C# code, including hard to read ternary operator statements such as below (demo purposes only) and similar constructs.
<%= Model.SupportsFeature ? Model.HasName ? "This model supports the feature and has a name" : "This model supports the feature and has no name" : "This model doesn't support the feature" %>
Now, should I keep this (still view-related) logic in the view, or should I instead:
1) Write a HtmlHelper GetSupportedText(this ... extension method?
2) Write an extension method to the actual Model class?
I'm trying to keep my code concise and keep related things together, but I'm really not sure how to structure this and deal with views that become cluttered with <% %>.
Thanks for your input on this!
EDIT: I am also concerned about putting out HTML from a C# helper method (as string) -- that's hard to debug an really ugly.
Upvotes: 2
Views: 194
Reputation:
This would go into a Helper class - preferably as an extension method. In there you can also apply localization (if you need to).
The other alternative is to create a new property (use a shared class if this is generated by Linq to Sql) that does this for you (outputs a conditional message). This way you can use the property with other outputs (like JSON etc).
Bottom line - do what works. You're right to remove the conditional stuff from the view - too hard to debug. If you throw it on the model you can test it as well :)
Upvotes: 2
Reputation: 2630
You can use the TagBuilder class to make HTML strings if you prefer it over String.Format() or string concatenation. I've also used the System.Xml.Linq classes for very complicated HTML.
The general rule that i follow is: "If there's an if, write an HTML helper." I can't claim credit for that statement, but I don't remember where I heard it. This rule is going to cause an explosion of HTML helper extensions, so I organize my extensions with namespaces. I make an extension namespace that is shared amongst views that I add to the web.config, and then I make view-specific extension code files and namespaces that I use for each specific view. This makes it much easier to find where your extensions reside if you organize your code in a logical manner and you won't have a huge amount of unnecessary helpers cluttering up your HTML object where they aren't needed.
Here's an example, using the default app name MvcApplication1.
Added to web.config to include my shared helpers in all views:
<pages>
<namespaces>
<add namespace="MvcApplication1.Helpers.Shared"/>
</namespaces>
</pages>
This is a simplified and contrived example of my view-specific helpers for Home/About.aspx.
namespace MvcApplication1.Helpers.About
{
public static class AboutViewExtensions
{
public static string AboutViewHelper(this HtmlHelper Html)
{
var tb = new TagBuilder("b");
tb.SetInnerText("bold text");
return tb.ToString(TagRenderMode.Normal);
}
}
}
Here's the About.aspx view using the <%@ Import %>
directive to bring in my namespace.
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcApplication1.Helpers.About" %>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>About</h2>
<p>
<%= Html.AboutViewHelper() %>
</p>
</asp:Content>
Upvotes: 3
Reputation: 26151
If you are using a ViewModel approach, you can stick this logic into a method/getter in your ViewModel.
Upvotes: 4