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; }
}

MVC 5 ViewModel,具有可枚举属性的EditorTemplate

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>
}

旁注:

  1. 您尚未发布CharacterAbilityScore的模型,因此有假设它包含属性Abbreviation(仅用于显示),并且AbilityId(与下拉列表关联)
  2. 不能在复杂对象上使用@Html.HiddenFor()(值将是对象的.ToString()输出)并且具有与下拉列表相同属性的@Html.HiddenFor()(以及位于@Html.DropDownListFor()之前)意味着您将绑定到post-back上的隐藏输入(即原始值,而不是从下拉列表中选择的值)
  3. 我还建议您的视图模型不要派生自DbContext。视图模型的用途是定义要定义的特性在视图中显示/编辑