I am trying to better understand the MVC pattern and separations of concerns, specifically about what constitutes "business logic". I was recently assigned to an existing asp.net mvc 4 project and have never used the MVC pattern before. As I have been familiarizing myself with the project and with MVC in general I found code in a View that looks similar to the following. Basically different lists of links are being generated depending on the mapLayer of the object opening the view (incidentally the original switch statement is nearly 100 lines long). It seems to me that this logic is "business logic" and should be re-factored into a model instead of being left in the view. Am I correct? and why, or why not?
Sample View Code Segment (generic):
<ul id="tabsMore">
@switch (Model.MapLayerId)
{
case "LayerID1":
<li><a href="@Url.Action("linkNameX", new { clientID = Model.Type1Model.clientID })">displayNameX<span> </span></a></li>
...
break;
case "LayerID2":
<li><a href="@Url.Action("linkNameY", new { clientID = Model.Type1Model.clientID })">displayNameY<span> </span></a></li>
...
if (int.Parse(@Model.ObjectId.Substring(3, 1)) > 3)
{
<li><a href="@Url.Action("linkNameZ", new {linkId = Model.ObjectId})">displayNameZ<span> </span></a></li>
...
}
...
break;
...
case "LayerIDN":
<li><a href="@Url.Action("linkNameZ", new { clientID = Model.Type2Model.clientID })">displayNameW<span> </span></a></li>
...
break;
}
</ul>
Is this business logic and should be moved from the view to a model?
Sometimes is really hard to tell, and can be religious from person to person. When I look at your code, I would say that the logic is not business logic. That does not mean it is or is not valid. Take a step back and realize that this logic can be in a controller or a view. A view with this logic means that you can reuse this model with different logic and get a different view, sometimes that is completely valid. Other times it should be in the controller so the view can only display what should be displayed. For instance some programmers want code in the controller to either return a view, partial view or json. If it's json, it has no logic, so that means whatever is on the other side needs the correct logic (unless it's in the controller, then all of it always matches, there is no choice).
I would prefer the code to look like:
<ul id="tabsMore">
@if (Model.IsLink)
{
<li><a href="@Url.Action(Model.LinkAction, new { linkId = Model.ID })">
@Model.DisplayName<span> </span></a></li>
}
else
{
<li><a href="@Url.Action(Model.LinkAction, new { clientID = Model.ID })">
@Model.DisplayName<span> </span></a></li>
}
</ul>
or if you are ok with empty parameters:
<ul id="tabsMore">
<li><a href="@Url.Action(Model.LinkAction,
new { linkId = Model.LinkID, clientId = Model.ClientId })">
@Model.DisplayName<span> </span></a></li>
</ul>
Although this might be impossible for technical reasons or business rules.