MVC 5 ViewModel,具有可枚举属性的EditorTemplate
本文关键字:枚举 属性 EditorTemplate ViewModel MVC | 更新日期: 2024-10-20 03:19:53
我正在努力找到完成以下操作的最佳正确方法:
我有一个名为CharacterViewModel的角色编辑器的ViewModel。此CharacterViewModel填充了一个Character对象,该对象是一个角色可以拥有的可用能力分数列表,位于另一个表中。
我为下拉列表创建了一个编辑模板,我正试图找到一种方法来恢复编辑后的能力列表。我似乎无法将它们重新连接到控制器上。
以下是ViewModel代码:
public class CharacterViewModel : DbContext
{
public Character Character { get; set; }
[UIHint("CharacterAbilityScores")]
public IEnumerable<CharacterAbilityScore> CharacterAbilityScores { get; set; }
public IEnumerable<SelectListItem> AbilityScoresSelectList { get; set; }
public IEnumerable<AbilityModifiersAndBonusSpellDTO> AbilityModifiersAndBonusSpellDTO { get; set; }
public CharacterViewModel()
: base("name=CharacterModels")
{
}
}
以下是用于填充ViewModel:的控制器代码
public async Task<ActionResult> Edit(int? id)
{
Character character = db.Characters.Find(id);
var model = new CharacterViewModel();
model.Character = character;
model.CharacterAbilityScores = character.CharacterAbilityScores;
// Creating the list of ability scores for the view
model.AbilityScoresSelectList = from amabs in db.AbilityModifiersAndBonusSpells
select new SelectListItem()
{
Value = amabs.score.ToString(),
Text = amabs.score.ToString()
};
return View(model);
}
控制器中的编辑方法签名(CharacterAbilityScores属性和其他复杂属性在回程时始终为空):
public async Task<ActionResult> Edit(CharacterViewModel characterViewModel)
以下是编辑视图中的相关代码:
@model CampaignManager.Models.CharacterViewModel
@using (Html.BeginForm())
{
<div class="form-group">
@Html.EditorFor(model => model.CharacterAbilityScores, new { AbilityScoresSelectList = Model.AbilityScoresSelectList })
</div>
}
最后,编辑器模板:
@model IEnumerable<CampaignManager.Entities.CharacterAbilityScore>
<table>
@foreach (var abilityScore in Model)
{
<tr>
<td>@abilityScore.Ability.Abbreviation</td>
<td>
@{
if (ViewData["AbilityScoresSelectList"] != null)
{
@Html.HiddenFor(z => abilityScore);
@Html.HiddenFor(z => abilityScore.AbilityId);
@Html.DropDownListFor(x => abilityScore.AbilityId, (IEnumerable<SelectListItem>)ViewData["AbilityScoresSelectList"], dropDownHTMLOptions);
}
}
</td>
<tr>
}
</table>
我尝试了许多不同的HiddeFor技巧,存储整个集合,存储不同的id。。。我承认我有点迷路了。也许我做错了,我需要另一种方法?
更新
以下是CharacterAbilityCore实体的模型:
public partial class CharacterAbilityScore
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CharacterId { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int AbilityId { get; set; }
public int AbilityScore { get; set; }
public virtual Ability Ability { get; set; }
public virtual AbilityModifiersAndBonusSpell AbilityModifiersAndBonusSpell { get; set; }
public virtual Character Character { get; set; }
}
EditorFor()
设计用于处理集合,其中EditorTemplate
是集合中的type
(在您的情况下,您已将EditorTemplate
的模型设置为集合(而不是type
),然后为每个元素提供重复的id
属性(无效html)和重复的name
属性(无法绑定到集合)。
将模板(Views/Shared/EditorTemplates/CharacterAbilityScore.cshtml
)更改为:
@model CampaignManager.Entities.CharacterAbilityScore
<tr>
<td>@Html.DisplatFor(m => m.Ability.Abbreviation)</td>
<td>@Html.DropDownListFor(m => m.AbilityId, (IEnumerable<SelectListItem>)ViewData["AbilityScoresSelectList"])</td>
</tr>
在主视图中为
@model CampaignManager.Models.CharacterViewModel
@using (Html.BeginForm())
{
<table>
@Html.EditorFor(model => model.CharacterAbilityScores, new { AbilityScoresSelectList = Model.AbilityScoresSelectList })
</table>
}
旁注:
- 您尚未发布
CharacterAbilityScore
的模型,因此有假设它包含属性Abbreviation
(仅用于显示),并且AbilityId
(与下拉列表关联) - 不能在复杂对象上使用
@Html.HiddenFor()
(值将是对象的.ToString()
输出)并且具有与下拉列表相同属性的@Html.HiddenFor()
(以及位于@Html.DropDownListFor()
之前)意味着您将绑定到post-back上的隐藏输入(即原始值,而不是从下拉列表中选择的值) - 我还建议您的视图模型不要派生自
DbContext
。视图模型的用途是定义要定义的特性在视图中显示/编辑