定义要从View传递到Controller的其他参数(使用DropDownList)

时间:2014-04-01 09:46:06

标签: c# asp.net .net asp.net-mvc scaffolding

我已经使用脚手架模板在Controller中创建了必要的部分,并为我的Model类创建了附带的视图问题如下图所示:

public class Question
    {
      [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      public int QuestionId { get; set; }

      [StringLength(250, ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "MaxCharsQuestionAchieved")]
      public string GeneralQuestion { get; set; }

      [StringLength(1000, ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "MaxCharsExplanationAchieved")]
      public string Explanation { get; set; }

      public bool IsTemplate { get; set; }

      public QuestionState QuestionState { get; set; }
      public DateTime DateSubmitted { get; set; }
      public DateTime? JudgementDate { get; set; }

      public virtual Regular Author { get; set; }

      public virtual List<Politician> AddressedPoliticians { get; set; }
      public virtual List<Topic> Topics { get; set; }

      public virtual Moderator LastEditor { get; set; }

      public virtual List<Attachment> Attachments { get; set; }
      public virtual List<Answer> Answers { get; set; }

      public virtual List<QuestionSubscription> QuestionSubscriptions { get; set; }


      public int FbShares { get; set; }
      public int FbLikes { get; set; }
      public int TwitterShares { get; set; }
      public int SiteVotes { get; set; }
}

我想更改“创建视图”的模板。如您所见,问题列出了AddressedPoliticians。我想向用户提供我数据库中所有政治家的下拉列表。值必须是政治家的id,​​显示成员应该是他们的FirstName。当然,View有一个类型为Question的模型。如何构建下拉列表并将选定的值提供给我的Create(问题问题)ActionResult方法,这样我就可以让Politician从数据库中删除,将其添加到问题中的AddressedPOliticians?

我试图摆弄ViewBag,但似乎无法让它工作。希望有人能给我一些提示/建议。

修改

我应该展示我已经尝试过的东西:)

ActionResult方法:

public ActionResult Create()
    {
      ViewBag.PolIds = new SelectList(context.Politicians.ToList(), "UserId", "FirstName");
      return View();
    }

    //
    // POST: /Question/Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Question question)
    {
      if (ModelState.IsValid)
      {
        var polId = ((SelectList)ViewBag.PolIds).SelectedValue;
        Politician pol = context.Politicians.Single(p => p.UserId == (int)polId);
        question.AddressedPoliticians.Add(pol);
        question.DateSubmitted = DateTime.Now;
        manager.CreateQuestion(question);
        return RedirectToAction("Index");
      }

      return View(question);
    }

Create.cshtml:

@model PoliticiOnline.DTO.Question

@{
    ViewBag.Title = "Stel een vraag!";
}

<h2>Stel een vraag!</h2>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Vraag</legend>

        <div class="general-question">
            <div class="editor-label">
                @Html.LabelFor(model => model.GeneralQuestion, "Algemene Vraag")
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.GeneralQuestion)
                @Html.ValidationMessageFor(model => model.GeneralQuestion)
            </div>
        </div>

        <div class="geadresseerde-politici">
            @Html.Label("Politicus")
            @Html.DropDownList("PolIds", "Kies een politicus...")
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Explanation, "Extra Uitleg")
        </div>
        <div class="editor-field">
            @Html.TextAreaFor(model => model.Explanation)
            @Html.ValidationMessageFor(model => model.Explanation)
        </div>

        <p>
            <input type="submit" value="Indienen!" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

2 个答案:

答案 0 :(得分:0)

对于下拉列表:创建值以作为List和属性选择以存储所选值(可能是int)。然后使用:

@Html.DropDownListFor(m => m.SelectedValue, Model.SelectListItems)

要获取复选框列表,您应添加包含所选政治家ID的列表或类似内容。然后添加一个复选框列表,其中包含名称=&#39;名称列表&#39;,值=&#39; id of politictian&#39;当然还有名称作为相关标签的文字。

我自己观点的一个例子:

<ul class="fields">
@foreach (var gender in Model.FilterData.Genders)
{
  <li class="field">
    <input id="gender@(gender.Id)" type="checkbox" name="Filters.Genders" value="@gender.Id" @(Model.Filters.Genders.Contains(gender.Id) ? "checked" : "") />
    <label for="gender@(gender.Id)">@gender.Name</label>
  </li>
}
</ul>

现在,我有一个可在我的Model.FilterData对象中选择的性别列表,每个对象都有一个Id和一个Name。我还有一个对象&#34;过滤器&#34;在我的模型中,带有列表性能。 因此,您可以看到每个复选框都有名称&#34; Filters.Genders&#34;,即指向此列表。

如果您只想选择一个,只需在模型中创建一个int属性,并将一系列radiobuttons绑定到同一个int属性。再举一个例子:

<ul class="fields">
  @foreach (var function in Model.FilterData.Functions)
  {
    <li class="field">
      @Html.RadioButtonFor(m => m.Filters.FunctionId, function.Id)
      @Html.LabelFor(m => m.Filters.FunctionId, function.Name)
    </li>
  }
</ul>

这可以更容易,因为您可以使用帮助程序功能。如您所见,每个radiobutton指向相同的模型属性(Filters.FunctionId) - 因此渲染的输入都将其作为名称。

如果在GET方法中使用,您将看到它多次重复相同的属性(即Filters.Genders = 2&amp; Filters.Genders = 4&amp; Filters.Genders = 5),这将被解析为列出你的行动。

答案 1 :(得分:0)

Question模型中添加字段:

[NotMapped]
public decimal PoliticianId { get; set; }

在您看来:

<div class="geadresseerde-politici">
            @Html.Label("Politicus")
@Html.DropDownListFor(model => model.PoliticianId, (SelectList)ViewBag.PolIds)
        </div>

在你的行动中:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Question question)
    {
      if (ModelState.IsValid)
      {
         var selectedPolitician = question.PoliticianId; // The selected politician id
      }
    }

修改

或者像mjepson在评论中提到的那样,您可以在不向Question模型中添加字段的情况下执行此操作,如:

在您看来:

<div class="geadresseerde-politici">
            @Html.Label("Politicus")
@Html.DropDownList("PoliticianId", (SelectList)ViewBag.PolIds)
        </div>

在你的行动中:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Question question, int PoliticianId) // PoliticianId will now have the selected value of the dropdown
    {
      if (ModelState.IsValid)
      {
         // do your stuff
      }
    }