我已经读过它generally a bad practice to use ViewBags并且混合ViewBag和ViewModel也不好,但是我使用一些ViewBags在我的控制器和视图之间传递sort order
参数,虽然我可以创建属性在视图ViewModel
上我需要的值才能在第一时间创建模型,所以无法看到如何解决这个问题。
控制器
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);
}
然后在我的视图中,我将使用ViewBag将值传递回控制器,例如我需要的sortOrder
,然后才能将其应用到构成我的NHibernate
查询中大部分方法,例如:
@Html.ActionLink("Name", "Index", new {sortOrder=ViewBag.NameSortParam,
includeComplete = ViewBag.IncludeCompleted})
我的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; }
}
答案 0 :(得分:3)
然后在我看来,我将使用ViewBag将值传递回 控制器
不,您将值传递给下一个控制器。当浏览器的新实例将处理请求时,(可能)在浏览器往返之后使用这些值。
由于您没有将任何内容传递回当前的控制器,因此无需使用ViewBag
。如果您愿意,可以将值放在模型中。
即使您将视图中的数据发送到控制器(这是非常不寻常的),使用该模型仍然可以实现。例如:
MyModel viewModel = new MyModel();
ActionResult result = View(viewModel);
// here you can access anything that the view would put in the model
return result;
当然,您不能使用控制器视图中的任何值来创建模型,因为您必须在视图之前创建模型。如果您需要视图中的任何数据来获取数据,您可以将其作为方法放在模型中而不是控制器中。
答案 1 :(得分:1)
我建议为您创建的每个视图创建一个ViewModel,因为您可能需要将更多信息传递给视图。
在这种情况下,您将拥有一个ViewModel,它具有分页列表数据的属性,您可以为SortOrder添加另一个属性。
例如:
public class MyViewModel
{
public IEnumerable<ToDo> TodoList { get; set; }
public string SortOrder { get; set; }
}
请参阅问题:ViewModel Best Practices