2

This is more of a architect question rather than one that requires code.

I have a page that requires me to display the status of a particular project. Let's say for the sake or brevity that there are two states, Open and Closed.

When the project is open I want to display a PartialView showing me one set of details. If the project is Closed I want to show a PartialView with different details.

Now I know I could do a check in the aspx and render one or the other but I'm trying to cut down on the number of decision points within the aspx code. I believe that there should be a minimum of actual code within the aspx.

Also, there are more then two states so the "if" statements would pile up and become messy.

Has anyone tackled something like this?

Should I create a Helper to do this? Can I, and I'm unsure how to do this, handle this in the ActionResult of the view? So for example, can I render the PartialViews in the action result and return that as part of the normal view?

3 Answers 3

7

You could do the logic in the controller and define a ViewData value that contains the name of the partial to render... so in the controller,

if (Project.Status == "Open") {
    ViewData["StatusPartial"] = "OpenPartial";
} else {
    ViewData["StatusPartial"] = "ClosedPartial";
}

Then in the aspx just do

<%=Html.RenderPartial(ViewData["StatusPartial"]) %>
Sign up to request clarification or add additional context in comments.

2 Comments

Very simple and keeps the logic where it should be. I like it.
This is by far the simplest solution, but it has a couple of flaws: * "Magic strings" (well, maybe not that magic - but they're not strongly typed) * Redundant saving of the project status information in two places (ViewData["StatusPartial"] and in the property of the model object)
5

If you code your project's status as an Enum, you could actually just get the correct partial to be shown without any if clauses at any point, using this neat trick:

<% Html.RenderPartial(Enum.GetName(typeof(ProjStat), prj.Status) + 'Partial'); %>

In the above example I've assumed that the name of the Enum is ProjStat, and that you have a naming convention of your partial views corresponding to OpenPartial.ascx and ClosedPartial.ascx for the two status values Open and Closed.

Comments

4

I like @Chris Gutierrez's solution, but I would use a property on your ViewModel rather than a named entry in ViewData. You might combine that with a Map on the controller to to save a little code -- the sample assumes that Status.Open maps to 0, and Status.Closed maps to 1.

private readonly static string[] StatusViews
     = new string[] { "OpenPartial", "ClosedPartial" };

...
model.StatusView = StatusViews[(int)Project.Status];


<%= Html.RenderPartial( Model.StatusView ) %>

3 Comments

+1. Right, and to make it extensible I could load in the values from a db or config.
This is a good modification of Chris's solution - however, it is likely that the view is already rendering other things about this project, and it seems redundant to have the status both as a property of the Project entity and as a separate property on the ViewModel.
Grnated I've only being working with MVC for a little over a year, but the pattern I've gravitated towards is a separate View-only model per view. This view model usually wraps the business model with a few extra items for the view such as, in this case, which partial to choose if there are options. I'm not sure exactly how I would handle this one -- I'm not as reluctant to use logic in my views and choosing how to render something does seem to me to be a function of the view not the controller. Probably I'd just use an if/then/else construct in the view based on the model property.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.