Dan*_*n P 18 c# asp.net-mvc-4 .net-4.5 razor-2
我对使用WPF/Silverlight的MVVM非常熟悉,但这是我第一次尝试使用MVC Web应用程序...这只是我的背景.
我创建了一个名为TestSitesController的控制器,它是从我的实体框架模型中的"站点"模型类(生成读/写操作和视图的模板)中自动生成的.我修改的唯一的东西是3个点,对于某些方法,有一个默认参数Guid id = null.我只是摆脱了"= null"一切正常.这是我改变的一个例子
public ActionResult Delete(Guid id = null)
{
//....
}
Run Code Online (Sandbox Code Playgroud)
这被改为
public ActionResult Delete(Guid id)
{
//....
}
Run Code Online (Sandbox Code Playgroud)
Site模型没有什么特别的SiteId,Abbreviation和DisplayName ...试图让这个问题尽可能简单.好的,所以我运行网站并转到htpp://.../TestSites/,一切都很完美.
我注意到我的所有视图(创建,删除,详细信息和编辑)都使用@model MVCWeb.MyEntities.Site,我现在完全可以使用它; 但在Index.cshtml视图中,我注意到它正在使用
@model IEnumerable<MVCWeb.MyEntities.Site>
Run Code Online (Sandbox Code Playgroud)
这适用于生成的模板,但我想使用"复合视图模型",也许这是我试图混合我的MVVM知识,但如果可能的话,将坚持使用.在我看来,复合视图模型只是一个特定于一个视图的模型,该视图由一个或多个实体模型以及像SelectedSiteId等其他属性组成.
所以我创建了一个非常简单的ViewModel,名为TestSitesViewModel
public class TestSitesViewModel
{
//Eventually this will be added to a base ViewModel to get rid
//of the ViewBag dependencies
[Display(Name = "Web Page Title")]
public string WebPageTitle;
public IEnumerable<MVCWeb.MyEntities.Site> Sites;
//Other Entities, IEnumberables, or properties go here
//Not important for this example
}
Run Code Online (Sandbox Code Playgroud)
然后在我的控制器中添加了一个名为IndexWithViewModel的动作方法
public ActionResult IndexWithViewModel()
{
var vm = new TestSitesViewModel();
vm.WebPageTitle = "Sites With Composite View Model";
vm.Sites = db.Sites.ToList();
return View(vm);
}
Run Code Online (Sandbox Code Playgroud)
然后我制作了一份Index.cshtml副本并将其命名为IndexWithModel.cshtml以匹配我的新ActionResult方法名称.我改变了顶线
@model IEnumerable<MVCWeb.MyEntities.Site>
Run Code Online (Sandbox Code Playgroud)
至
@model MVCWeb.Models.TestSitesViewModel
Run Code Online (Sandbox Code Playgroud)
我在表部分之前添加了这个来测试DisplayNameFor和DisplayFor
@Html.DisplayNameFor(model => model.WebPageTitle)
@Html.DisplayFor(model => model.WebPageTitle)
<br />
Run Code Online (Sandbox Code Playgroud)
改变了
@foreach (var item in Model) {
Run Code Online (Sandbox Code Playgroud)
至
@foreach (var item in Model.Sites) {
Run Code Online (Sandbox Code Playgroud)
并注释掉了包含所有表头的tr部分.除了@ Html.DisplayNameFor显示变量名称"WebPageTitle"而不是使用"Web页面标题"(如数据注释的Display属性中所示)之外,一切都运行良好.
[Display(Name = "Web Page Title")]
public string WebPageTitle;
Run Code Online (Sandbox Code Playgroud)
此外,如果我在包含表头信息的tr部分中回复.我不能为我的生活弄清楚放入什么我已经尝试过model.Sites.Abbreviation,model.Sites [0].缩写,以及各种其他组合但是得到错误.
<tr>
<th>
@Html.DisplayNameFor(model => model.Abbreviation)
</th>
<th>
@Html.DisplayNameFor(model => model.DisplayName)
</th>
<th></th>
</tr>
Run Code Online (Sandbox Code Playgroud)
那我应该在那里使用什么?我不太清楚为什么model.Sites.Abbreviation不起作用,因为Sites是与原始Index.cshtml中的模型完全相同的类型
Dan*_*n P 21
经过几个小时的捣乱,我终于弄明白了.
第一个问题是,为了在Data Anotations中使用Display arrtibute,必须添加get和set acessor方法,即使它们只是默认方法.我假设这是因为它们只能用于属性,而不能用于类的公共数据成员.这是获得的代码
@Html.DisplayNameFor(model => model.WebPageTitle)
Run Code Online (Sandbox Code Playgroud)
工作正常
public class TestSitesViewModel
{
//Eventually this will be added to a base ViewModel to get rid of
//the ViewBag dependencies
[Display(Name = "Web Page Title")]
public string WebPageTitle { get; set; }
//PUBLIC DATA MEMBER WON'T WORK
//IT NEEDS TO BE PROPERTY AS DECLARED ABOVE
//public string WebPageTitle;
public IEnumerable<MVCWeb.MyEntities.Site> Sites;
//Other Entities, IEnumberables, or properties go here
//Not important for this example
}
Run Code Online (Sandbox Code Playgroud)
第二部分问题是在IEnumerable变量中访问元数据.我声明了名为headerMetadata的临时变量,并使用它而不是尝试通过IEnumerable访问属性
@{var headerMetadata = Model.Sites.FirstOrDefault();}
<tr>
<th>
@Html.DisplayNameFor(model => headerMetadata.Abbreviation)
</th>
<th>
@Html.DisplayNameFor(model => headerMetadata.DisplayName)
</th>
...
Run Code Online (Sandbox Code Playgroud)
这确实提出了headerMetadata变量何时超出范围的问题?它可用于整个视图还是仅限于html表标签?我想这是另一个日期的另一个问题.
| 归档时间: |
|
| 查看次数: |
22737 次 |
| 最近记录: |