如何在Ajax.BeginForm()中手动设置属性值

时间:2016-03-06 03:30:37

标签: c# asp.net-mvc razor asp.net-mvc-viewmodel ajax.beginform

我已经分享了下面的视图和视图模型。我使用optgroup循环而不是使用某些foreach帮助程序填充了缩进的选择列表(使用@Html)。但是,我不知道如何将列表中的选定值分配给CreateMainEntryViewModel的特定属性。更具体地说,我需要根据提交表单时在下拉列表中所做的选择来设置DiscussionWallIdTimeFrameId属性值。在此任务中,我使用Ajax.BeginForm()

@model EcholuMvc.Models.CreateMainEntryViewModel
@using (Ajax.BeginForm("CreateMainEntry", "MainEntry", new AjaxOptions
{     
    UpdateTargetId = "div_MainEntries",
    InsertionMode = InsertionMode.Replace
}))
{       

     @Html.TextBoxFor(m => m.Title, new { placeholder = "Write a brief title...", @class = "form-control input-lg" })

     @Html.TextAreaFor(m => m.Content, new { placeholder = "Type your entry here...", @class = "form-control mainEntryField" })

     <label for="drp_DiscussionWallListForNewMainEntry" style="text-align:right" class="col-sm-3 control-label">Choose the Discussion Wall:</label>

     <select id="drp_DWListForNewMainEntry" class="form-control">
     @{
          foreach (DiscussionWall dw in Model.DiscussionWalls)
          {
               <optgroup label="@dw.WallTitle">
               foreach (TimeFrame tf in dw.TimeFrames)
               {
                  <option data-dw="@dw.WallId" data-tf="@tf.TimeFrameId">@tf.TimeFrameName</option>
               }              
                </optgroup>
         }
     }
     </select>

    <button type="submit" id="btn_SubmitNewPost">Post</button>                           

}

这是viewmodel:

public class CreateMainEntryViewModel
{

    public string Title { get; set; }

    public string Content { get; set; }

    public Boolean IsAnonymous { get; set; }

    public int DiscussionWallId { get; set; }

    public int TimeFrameId { get; set; }

    public CreateMainEntryViewModel(List<DiscussionWall> walls)
    {
        DiscussionWalls = walls;
    }

    public List< DiscussionWall> DiscussionWalls { get; set; }
}

我感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

要直接回答您的问题,您需要为DiscussionWallId属性添加隐藏输入,为name元素添加<select>属性,为其添加value属性<option>元素,并使用javascript / jquery根据所选选项更新隐藏输入的值。

@Html.HiddenFor(m => m.DiscussionWallId) // add
<select name="TimeFrameId" id="TimeFrameId" class="form-control"> // add name attribute
@{
  foreach (DiscussionWall dw in Model.DiscussionWalls)
  {
    <optgroup label="@dw.WallTitle">
      foreach (TimeFrame tf in dw.TimeFrames)
      {
        <option data-dw="@dw.WallId" value="@tf.TimeFrameId">@tf.TimeFrameName</option> // modify
      }              
  </optgroup>
}
</select>

并更新隐藏输入的值

$('#TimeFrameId').change(function() {
    var dw = $(this).children('option:selected).data('dw');
    $('#DiscussionWallId').val(dw);
});

现在,当您提交表单时,DiscussionWallIdTimeFrameId属性都会被绑定。

然而,添加隐藏输入(以及您的data-dw属性)是不必要的(恶意用户可以轻松更改隐藏输入的值,可能导致您的应用失败)。如果由于任何原因您需要与所选DiscussionWallId关联的TimeFrame属性,那么您应该根据TimeFrameId的值从存储库中获取该值。

还有很多其他原因导致这种设计很糟糕,包括你没有获得强类型的双向模型绑定,你也无法使用内置的客户端验证功能。

如果您使用的是MVC-5.2,那么您可以使用SelectListItemGroup属性或接受dataGroupField值的SelectList重载来生成{ {1}}支持视图中的分组选项,然后只使用强类型IEnumerable<SelectListItem>帮助器。但是,如果您有一些@Html.DropDownListFor()个对象,并且每个对象只包含几个DiscussionWalls个对象,那么这实际上是合适的。如果没有,那么您应该实现级联下拉列表。有关示例,请参阅this answerthis DotNetFiddle