【问题标题】:Passing ViewModel List Data to controller将 ViewModel 列表数据传递给控制器
【发布时间】:2018-04-09 07:53:55
【问题描述】:

我有一个这样的 ViewModel:

public class AddNewsModel
{
    public List<CategoriesModel> Category { get; set; }

    public NewsModel NewsModel { get; set; }
}

其中类别包含:

public class CategoriesModel
{
    public string Name { get; set; }

    public int ID { get; set; }
}

NewsModel 包含:

public class NewsModel
{
    public int ID { get; set; }
    public string Category { get; set; }
    public String Headline { get; set; }
    public string Source { get; set; }
    public DateTime Publish_Date { get; set; }
    public string Text { get; set; }
    public string Summary { get; set; }

    public string TimeAgo { get; set; }

    public string ImageURL { get; set; }

    public string CategoryID { get; set; }
}

我有一个视图,我在其中使用 NewsModel 为新闻获取表单输入,但我想将可能的类别显示为下拉列表或从 CategoriesModel 中选择标签。

这是我的观点:

<h2>Add a News Article</h2>
@if (TempData["Success"] != null)
{
    <p class="alert alert-success" id="successMessage">@TempData["Success"]</p>
}
@using (Html.BeginForm("AddNews", "Admin", FormMethod.Post))
{

    @Html.AntiForgeryToken()
    <div class="form-horizontal" id="addNews">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.Label("News ID", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-1">
                @Html.EditorFor(model => model.NewsModel.ID, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.ID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Category, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.DropDownListFor(model => model.Category, new SelectList(Model.Category), "Select Category")
            @*<div class="col-md-2">
                    <select form="addNews" id="NewsModel_Category" name="NewsModel.Category">
                        @foreach (var item in Model.Category)
                        {
                            <option value="@item.Name">@item.Name</option>
                        }
                    </select>
                </div>*@
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Headline, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.EditorFor(model => model.NewsModel.Headline, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Headline, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Source, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.EditorFor(model => model.NewsModel.Source, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Source, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.Label("Publish Date", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-4">
                @Html.EditorFor(model => model.NewsModel.Publish_Date, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Publish_Date, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Text, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.TextAreaFor(model => model.NewsModel.Text, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Text, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Summary, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.TextAreaFor(model => model.NewsModel.Summary, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Summary, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.ImageURL, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.EditorFor(model => model.NewsModel.ImageURL, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.ImageURL, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

这行代码:

@Html.DropDownListFor(model => model.Category, new SelectList(Model.Category), "Select Category")

获取所有类别,但仅将它们显示为我在视图中导入的模型,即。 “MVCApplication.Models.AddNewsModel”,而不是像“World”或“Tech”这样的类别

当我尝试使用 formcollection 在我的 HTTPPost 控制器操作中获取数据时,我评论过的这段代码返回 null。我尝试使用我提供的 ID:string x= formCollection["category"];

 <div class="col-md-2">
                        <select form="addNews" id="category" name="category">
                            @foreach (var item in Model.Category)
                            {
                                <option value="@item.Name">@item.Name</option>
                            }
                        </select>
                    </div>

如何在我的视图中显示类别,以及在控制器中获取值? 任何帮助将不胜感激。

编辑:

我将控制器操作中的类别列表填充为:

public ActionResult AddNews()
    {
        AddNewsModel AddNewsModel = new AddNewsModel();
        AddNewsModel.Categories = new NewsArticles().GetCategories();
        return View(AddNewsModel);
    }

将我的模型更改为 Ienumerable 而不是列表会导致我的控制器出现错误,我似乎无法解决。

【问题讨论】:

  • new SelectList(Model.Category, "Id", "Name")(但您的视图模型应该包含属性IEnumerable&lt;SelectListItem&gt; CategoryList,而不是List&lt;CategoriesModel&gt;)。并且您不能对要绑定的属性和 SelectList 使用相同的名称。必须是@Html.DropDownListFor(m =&gt; m.NewsModel.Category, ...)
  • 我尝试了这个以及@Irakli 的答案在我的控制器操作中明确投射后,它可以工作

标签: asp.net-mvc viewmodel


【解决方案1】:

你的模型应该是这样的:

public class AddNewsModel
{
    public IEnumerable<SelectListItem> CategorySelectList { get; set; }

    public int CategoryId {get; set;}

    public NewsModel NewsModel { get; set; }
}

在视图中:

@Html.DropDownListFor(model => model.CategoryId, Model.CategorySelectList, "Select Category")

更多详情 -> link

【讨论】:

  • 如果我在控制器中填充类别,我必须在以下代码中进行哪些更改? public ActionResult AddNews() { AddNewsModel AddNewsModel = new AddNewsModel(); AddNewsModel.Categories = new NewsArticles().GetCategories(); return View(AddNewsModel); }
  • AddNewsModel.CategorySelectList = new NewsArticles().GetCategories().Select(x=> new SelectListItem(){ Text= x.Name, Value = x.ID.ToString(); }) 我认为它应该工作
【解决方案2】:

您应该同时拥有包含模型中所有类别的类别和列表

public class AddNewsModel
{
    public int Category { get; set; }
    public IEnumerable<SelectListItem> Categories { get; set;}
    public NewsModel NewsModel { get; set; }
}

查看

使用列表更新您的下拉列表。

<h2>Add a News Article</h2>
@if (TempData["Success"] != null)
{
    <p class="alert alert-success" id="successMessage">@TempData["Success"]</p>
}
@using (Html.BeginForm("AddNews", "Admin", FormMethod.Post))
{

    @Html.AntiForgeryToken()
    <div class="form-horizontal" id="addNews">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.Label("News ID", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-1">
                @Html.EditorFor(model => model.NewsModel.ID, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.ID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Category, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.DropDownListFor(model => model.Category, Model.Categories, "Select Category")
            @*<div class="col-md-2">
                    <select form="addNews" id="NewsModel_Category" name="NewsModel.Category">
                        @foreach (var item in Model.Category)
                        {
                            <option value="@item.Name">@item.Name</option>
                        }
                    </select>
                </div>*@
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Headline, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.EditorFor(model => model.NewsModel.Headline, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Headline, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Source, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.EditorFor(model => model.NewsModel.Source, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Source, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.Label("Publish Date", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-4">
                @Html.EditorFor(model => model.NewsModel.Publish_Date, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Publish_Date, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Text, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.TextAreaFor(model => model.NewsModel.Text, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Text, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.Summary, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.TextAreaFor(model => model.NewsModel.Summary, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.Summary, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.NewsModel.ImageURL, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-6">
                @Html.EditorFor(model => model.NewsModel.ImageURL, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewsModel.ImageURL, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

【讨论】:

  • ' @Html.DropDownListFor(model => model.Category, IEnumerable Categories, "Select Category")' 在视图中抛出错误,指出“使用通用 Ienumerable 需要 1 个类型参数” , "'SelectListItem' 是在给定上下文中无效的类型", "名称类别在当前上下文中不存在。"
  • 您的代码甚至无法编译!如果它这样做了,它会抛出一个异常。
  • 反对者.. 请发表评论。它有助于改善答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多