There has been many discussion on ASP.NET MVC and Codebehind-files, mostly where it has been pointed out that these Codebehind-files are evil.
So my question is, how do you handle page-specific logic?
What we don't want here is spaghetti-code in the inline-code and we don't want page-specific code scattered throughout helper-classes or on top of the HTML-helper-class.
An example would be:
<% for(int i = 0; i < companyList.Count; i++) { %>
RenderCompanyNameWithRightCapsIfNotEmpty(company, i)
<% } %>
With accompanying codebehind:
private string RenderCompanyNameWithRightCapsIfNotEmpty(string company, index)
{
if (index == 0) {
return string.Format("<div class=\"first\">{0}</div>", company);
}
// Add more conditional code here
// - page specific HTML, like render a certain icon
string divClass = (index % 2 == 0) ? "normal" : "alternate";
return string.Format("<div class=\"{1}\">{0}</div>", company, divClass);
}
This will only be used on one page and is most likely subject to change.
Update: A couple approaches I thought about where these:
1) Inline codebehind on page - with simple methods that returns strings.
<script runat="server">
private string RenderCompanyHtml(string companyName) ...
<script>
2) Putting a method which returns a string in the Controller. But that would be putting View-logic into the Controller.
public class SomeController : Controller
{
[NonAction]
private static string RenderCompanyHtml(string companyName) ...
public ActionResult Index() ...
}
You should put that code in the controlleraction where you prepare the viewdata.
I usually make a region "helper methods" in my controller class with a few [NonAction] methods to keep things clean.
So my (simplified) controller would look like this:
public class SomeController : Controller
{
#region Helper methods
[NonAction]
private static string CompanyNameWithRightCapsIfNotEmpty(string company)
{
if (string.IsNullOrEmpty(company)) {
return company;
}
return UpperCaseSpecificWords(company);
}
#endregion
public ActionResult Companies()
{
var companies = GetCompanies();
var companyNames = companies.Select(c => CompanyNameWithRightCapsIfNotEmpty(c.Name));
ViewData["companyNames"] = companyNames;
return view();
}
}
Helper methods are one good way of handling page specific code, but I think it is a;ways preferable to get your model to show the data you need.
If you're going to go for the helper option, you would be better served by making the operation it perfroms a bit less page specific. If your method RenderCompanyNameWithRightCapsIfNotEmpty has to be so specific it would be better if your model provided it. One way would be to have the model provide a list with the text already formatted, and expose it as a public property (say an IEnumerable of formatted company names).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With