【发布时间】:2014-11-27 21:36:01
【问题描述】:
我对通过 POST 接收复杂 ViewModel 的操作存在问题,并且它的所有对象组件均为空,即使我已在操作中初始化它们并使用 GET 方法将整个 ViewModel 返回到视图。
让我解释一下情况。我有一个包含三个部分的视图的复杂模型:Applicant 详细信息、Application 详细信息和Recordings 的列表。这个视图很复杂,(1) 让我查看我正在为其创建应用程序的 Applicant 的详细信息,(2) 有一个我想从中选择的录音列表,然后我可以添加到 Application。这是我的 ViewModel:
public class ApplicantApplicationRecordingsViewModel
{
// Applicant
public Applicant Applicant { get; set; }
// Application
public Application Application { get; set; }
public SelectList UsageTypeSelectList { get; private set; }
public SelectList UsageEndAppSelectList { get; private set; }
// Recordings
public IEnumerable<RecordingViewModelApp>
RecordingsViewModelApp { get; set; }
public ApplicantApplicationRecordingsViewModel()
: this(new MyDBContext())
{
}
public ApplicantApplicationRecordingsViewModel(MyDBContext dbContext)
{
PopulateUsageTypeSelectList(dbContext);
PupulateUsageEndAppSelectList(dbContext);
}
private void PopulateUsageTypeSelectList(MyDBContext dbContext,
int? usageTypeSelected = null)
{
IEnumerable<UsageType> utQuery =
dbContext.UsageTypes.OrderBy(
ut => ut.UsageTypeName).ToList();
this.UsageTypeSelectList =
new SelectList(utQuery,
"UsageTypeID",
"UsageTypeName",
usageTypeSelected);
}
private void PupulateUsageEndAppSelectList(
MyDBContext dbContext,
int? usageEndAppSelected = null)
{
IEnumerable<UsageEndApp> ueaQuery =
dbContext.UsageEndApps.OrderBy(uea => uea.UsageEndAppName).ToList();
this.UsageEndAppSelectList =
new SelectList(ueaQuery,
"UsageEndAppID",
"UsageEndAppName",
usageEndAppSelected);
}
}
在控制器中,我只需为RecordingViewModelApp 填充记录列表,将申请人的详细信息放入Applicant 并将Application 对象留空以填充到视图中。
public ActionResult Create(int? ApplicantID)
{
if (ApplicantID == null)
{
// Error 400. Bad Request Exception
}
ApplicantApplicationRecordingsViewModel viewModel = null;
using (MyDBContext dbContext = new MyDBContext())
{
Applicant applicant =
dbContext.Applicants.Find(ApplicantID);
if (applicant == null)
{
// Error 404. Http not found
}
List<RecordingViewModelApp> recordings =
getViewModel(
dbContext.Recordings.ToList(),
dbContext);
viewModel =
new ApplicantApplicationRecordingsViewModel(dbContext);
viewModel.Applicant = applicant;
viewModel.RecordingsViewModelApp = recordings;
}
return View(viewModel);
}
问题是当我将 ViewModel (ApplicantApplicationRecordingsViewModel) 返回到 [HttpPost] Create() Action 时,所有 View Model 的组件都是空的,例如RecordingViewModelApp 的列表为空。我错过了什么?我需要了解幕后发生的事情以及为什么默认模型绑定不起作用。
[HttpPost]
[ActionName("Create")]
public ActionResult Create_post(
ApplicantApplicationRecordingsViewModel viewModelToValidate)
{
// Validation against Application only and TryToUpdate() etc.
}
干杯!
编辑:
观点
@model Project.ApplicantApplicationRecordingsViewModel
@{
string applicantDetails = string.Format("{0} {1} {2}",
Model.Applicant.title, Model.Applicant.firstName, Model.Applicant.lastName);
ViewBag.Title = "Create a new application for " + applicantDetails;
}
<h2>@ViewBag.Title</h2>
<hr />
@using (Html.BeginForm())
{
<h3>Details of the applicant</h3>
@Html.HiddenFor(item => Model.Applicant.ApplicantID)
@Html.HiddenFor(item => Model.Application.ApplicationID)
<table>
<tr>
<th>@Html.DisplayNameFor(item => Model.Applicant.title)</th>
<th>@Html.DisplayNameFor(item => Model.Applicant.firstName)</th>
<th>@Html.DisplayNameFor(item => Model.Applicant.lastName)</th>
<th>@Html.DisplayNameFor(item => Model.Applicant.telephone)</th>
<th>@Html.DisplayNameFor(item => Model.Applicant.mobile)</th>
<th>@Html.DisplayNameFor(item => Model.Applicant.email)</th>
</tr>
<tr>
<td class="display-field">@Html.DisplayFor(item => Model.Applicant.title)</td>
<td class="display-field">@Html.DisplayFor(item => Model.Applicant.firstName)</td>
<td class="display-field">@Html.DisplayFor(item => Model.Applicant.lastName)</td>
<td class="display-field">@Html.DisplayFor(item => Model.Applicant.telephone)</td>
<td class="display-field">@Html.DisplayFor(item => Model.Applicant.mobile)</td>
<td class="display-field">@Html.DisplayFor(item => Model.Applicant.email)</td>
</tr>
</table>
<hr /> // ----------------------------------------------------------------------------------------------
<h3>Details of the application</h3>
<table id="main">
<tr>
<td>
<table>
<tr>
<td class="editor-label first-label">@Html.DisplayNameFor(item => Model.Application.ApplicationNo)</td>
<td class="editor-field">
@Html.EditorFor(item => Model.Application.ApplicationNo)
@Html.ValidationMessageFor(item => Model.Application.ApplicationNo)
</td>
</tr>
<tr>
<td class="editor-label first-label">@Html.DisplayNameFor(item => Model.Application.StartDate)</td>
<td class="editor-field">
@Html.EditorFor(item => Model.Application.StartDate)
@Html.ValidationMessageFor(item => Model.Application.StartDate)
</td>
</tr>
<tr>
<td class="editor-label first-label">@Html.DisplayNameFor(item => Model.Application.EndDate)</td>
<td class="editor-field">
@Html.EditorFor(item => Model.Application.EndDate)
@Html.ValidationMessageFor(item => Model.Application.EndDate)
</td>
</tr>
<tr>
<td class="editor-label first-label">@Html.DisplayNameFor(item => Model.Application.UsageTypeID)</td>
<td class="editor-field">
@Html.DropDownListFor(item => Model.Application.UsageTypeID, Model.UsageTypeSelectList, "-- Select Usage --")
@Html.ValidationMessageFor(item => Model.Application.UsageTypeID)
</td>
</tr>
<tr>
<td class="editor-label first-label">@Html.DisplayNameFor(item => Model.Application.UsageEndAppID)</td>
<td class="editor-field">
@Html.DropDownListFor(item => Model.Application.UsageEndAppID, Model.UsageEndAppSelectList, "-- Select Type --")
@Html.ValidationMessageFor(item => Model.Application.UsageEndAppID)
</td>
</tr>
<tr>
<td class="editor-label first-label">@Html.DisplayNameFor(item => Model.Application.linkToPaperVer)</td>
<td class="editor-field">
@Html.EditorFor(item => Model.Application.linkToPaperVer)
@Html.ValidationMessageFor(item => Model.Application.linkToPaperVer)
</td>
</tr>
</table>
</td>
<td class="editor-label">
@Html.DisplayNameFor(item => Model.Application.Info)
</td>
<td class="editor-field">
@Html.EditorFor(item => Model.Application.Info)
@Html.ValidationMessageFor(item => Model.Application.Info)
</td>
</tr>
</table>
<hr /> // ----------------------------------------------------------------------------------------------
<h3>List of recordings</h3>
Html.RenderPartial("~/Views/Recordings/_List_App.cshtml", Model.RecordingsViewModelApp);
<hr /> // ----------------------------------------------------------------------------------------------
<p>
<input type="submit" value="Create" />
</p>
}
<div>
@Html.ActionLink("Back to List", "Index", "Applicants")
</div>
编辑 2
部分视图:
@model IEnumerable<Project.ViewModels.RecordingViewModelApp>
@if (Model != null)
{
<div>
<table class="data-in-table">
<tr>
<th>@Html.DisplayNameFor(model => model.IsSelected)</th>
<th>@Html.DisplayNameFor(model => model.FileLocation)</th>
<th>@Html.DisplayNameFor(model => model.EnteredDate)</th>
<th>@Html.DisplayNameFor(model => model.Duration)</th>
<th>@Html.DisplayNameFor(model => model.Status)</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td class="display-field">@Html.EditorFor(model => item.IsSelected)</td>
<td class="display-field">@Html.DisplayFor(model => item.FileLocation)</td>
<td class="display-field">@Html.DisplayFor(model => item.EnteredDate)</td>
<td class="display-field">@Html.DisplayFor(model => item.Duration)</td>
<td class="display-field">@Html.DisplayFor(model => item.Status)</td>
</tr>
}
</table>
</div>
}
else
{
<h3>No recordings attached to this Patient</h3>
}
编辑 3
RecordingViewModelApp:
public class RecordingViewModel
{
public int RecordingID { get; set; }
public string FileLocation { get; set; }
public DateTime EnteredDate { get; set; }
public int Duration { get; set; }
public string Status { get; set; }
}
public class RecordingViewModelApp : RecordingViewModel
{
public bool IsSelected { get; set; }
}
【问题讨论】:
-
你能发表你的看法吗?
-
您是否尝试过不在视图中调用
Model,而是使用item@Html.EditorFor(item => item.Application.ApplicationNo)。如果没有帮助,请添加视图的渲染 HTML 代码 -
我现在做不到。 VS2010安装在不同的机器上,所以我必须等到明天。我只能说当模型从 GET 操作返回时正确呈现视图。当它返回 POST 时,组件为空。渲染的
PartialView是通过DisplayFor和DisplayNameFor等所有助手引用RecodingViewModel。我不知道这会如何影响模型本身! -
您需要从渲染的 HTML 中发布输入的名称,然后就会清楚为什么您的操作中有空值 :)
-
停止使用这种不良做法! (在视图模型中使用
MyDBContext,用于布局的html 表等)模型绑定正在工作,但它需要绑定值!除了ApplicantID之外,您不会为Applicant的任何属性呈现控件,这就是绑定的所有内容。您使用RenderPartial进行录制并仅将模型的属性传递给它,因此控件名称与您的模型属性不匹配,因此它也将为空。您还没有显示部分视图,很难理解 我想选择并添加到应用程序 的意思
标签: c# asp.net-mvc asp.net-mvc-4