I've read that it's generally a bad practice to use ViewBags and also bad to mix ViewBag and ViewModels, but I'm using some ViewBags to pass sort order
parameters between my controller and view and though I can create the properties on the ViewModel
for the view I need the values before I can create the model in the first place, so can't see how to get around this.
Controller
public ActionResult Index(string sortOrder, string searchString,
string currentFilter, int? page,
bool? includeComplete)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParam = string.IsNullOrWhiteSpace(sortOrder) ? "Name desc" : "";
ViewBag.DateSortParam = sortOrder == "Date" ? "Date desc" : "Date";
if (Request.HttpMethod == "GET")
searchString = currentFilter;
else
page = 1;
ViewBag.CurrentFilter = searchString;
bool showCompleted = (includeComplete == null || includeComplete == false)
? false : true;
ViewBag.IncludeCompleted = showCompleted;
int pageNumber = (page ?? 1);
var query = Session.QueryOver<ToDo>();
if (!string.IsNullOrWhiteSpace(searchString))
query = query.WhereRestrictionOn(td => td.TaskName)
.IsInsensitiveLike(string.Format("%{0}%", searchString));
if (!showCompleted)
query.And(td => td.IsComplete == false);
switch (sortOrder)
{
case "Name desc":
query = query.OrderBy(td => td.TaskName).Desc;
break;
case "Date":
query = query.OrderBy(td => td.DueDate).Asc;
break;
case "Date desc":
query = query.OrderBy(td => td.DueDate).Desc;
break;
default:
query = query.OrderBy(td => td.TaskName).Asc;
break;
}
var result = query.Fetch(p=>p.Priority).Eager
.Fetch(s=>s.Staff).Eager
.List();
var viewModel = AutoMapper.Mapper.Map<IEnumerable<ToDo>,
IEnumerable<IndexToDoViewModel>>(result)
.ToPagedList(pageNumber, PageSize);
return View(viewModel);
}
Then in my view I'll use the ViewBag to pass values back to the controller, such as the sortOrder
which I need to have before I can apply it in my NHibernate
query that forms the bulk of the method, for example:
@Html.ActionLink("Name", "Index", new {sortOrder=ViewBag.NameSortParam,
includeComplete = ViewBag.IncludeCompleted})
My ViewModel
public class IndexToDoViewModel
{
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]
[DisplayName("Date Due")]
public DateTime? DueDate { get; set; }
public Guid Id { get; set; }
[DisplayName("Is Complete")]
public bool IsComplete { get; set; }
[DataType(DataType.MultilineText)]
public String Notes { get; set; }
public string Priority { get; set; }
public string Staff {get; set;}
[DisplayName("Name")]
public String TaskName { get; set; }
// These would potentially replace my ViewBag?
public string CurrentSort { get; set; }
public string CurrentFilter { get; set; }
public string NameSortParam { get; set; }
public string DateSortParam { get; set; }
public bool IncludeCompleted { get; set; }
}