我试图找到最合适的方法来执行以下操作:
我有一个名为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>
我尝试了许多不同的HiddenFor技巧,存储了整个收藏品,存储了不同的ID ...我在那里迷失了一点点我会承认。也许我这样做是错的,我还需要另一种方法吗?
更新
以下是CharacterAbilityScore实体的模型:
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; }
}
答案 0 :(得分:1)
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()
之前)意味着你将绑定
回发后的隐藏输入(即原始值,而不是
从下拉列表中选择的值DbContext
派生的。
视图模型的目的是定义您想要的属性
在视图中显示/编辑