为基于自身的多选下拉列表创建一个字段(无需创建新模型)

时间:2018-08-29 19:02:48

标签: asp.net-mvc asp.net-mvc-4

我试图为我的BugTracker实现多选下拉列表功能,但似乎找不到不涉及创建另一个模型的解决方案。运作方式如下:

我有一个名为Report的模型,其中包含有关错误的信息。该模型包含诸如错误名称,紧急度,提交日期,解决方案等字段。我想要添加的字段实际上是相关错误的列表。因此,当程序员更新该报告时,他可以从以前的错误(报告)列表中进行选择,并添加多个报告编号。查看(未编辑)报告时,这些数字将作为ActionLink出现在报告页面上。所以也许用户看到了:

相关错误:1、37、56

其背后的代码如下:

相关错误:@ Html.ActionLink(“ 1”,“ Admin”,“ Report”,1,空),@ Html.ActionLink(“ 37”,“ Admin”,“ Report”,37,null),@ Html.ActionLink(“ 56”,“ Admin”,“ Report”,56,null)

(这些数字实际上是下面的Report.cs的ID。)

因此,在表单的“编辑”视图上,将出现一个多选下拉列表,您可以在其中选择所有这些错误。这类似于https://harvesthq.github.io/chosen/,在多选区域中,您可以看到所有错误/报告及其关联ID的列表。甚至只是ID列表!

在典型视图上,您​​将看到上面的内容。

如何使它正常工作?

让我给我我自己的代码,告诉我我的意思(代码被截断了,使问题更容易了):

Report.cs(模型)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace BugTracker.Models
{
    public class Report
    {
        //For User
        public int ID { get; set; }
        public String Name { get; set; }
        public String Description { get; set; }
        public String Solution { get; set; }    
    }
}

AdminReport.cshtml(查看)

@model BugTracker.Models.Report
@{
    ViewBag.Title = "Report";
    Layout = "~/Views/Shared/_Layout.cshtml";
}


<h1>@Model.Name</h1>
Description: @Model.Description <br /> <br />
Solution: @Model.Solution    <br /> <br>

还有用于编辑的表格...

AdminReportForm.cshtml

@model  BugTracker.ViewModels.UserReportViewModel

@{
    ViewBag.Title = "Issue Form";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Update Issue</h1>    
@Model.Report.Name <br />    
@using (Html.BeginForm("SaveAdmin", "Report"))
{
    <div class="form-group">
        <label>Solution</label>
        @Html.TextAreaFor(m => m.Report.Solution, new { @class = "form-control", @rows="10"})
    </div>
    @Html.HiddenFor(m => m.Report.ID)
    <button type="submit" class="btn btn-primary">Save</button>
}

我的viewmodel(实际的ViewModel包含几个其他字段):

UserReportViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BugTracker.Models;
using System.Web.Mvc;

namespace BugTracker.ViewModels
{
    public class UserReportViewModel
    {
        public Report Report { get; set; }    
    }
}

控制器...

(对于AdminReport.cshtml)

    public ActionResult Admin(int id)
    {
        var report = _context.Reports.SingleOrDefault(c => c.ID == id);
        if (report == null)
            return HttpNotFound();

        var viewModel = new UserReportViewModel
        {
            Report = report,
        };

        return View("AdminReport", report);
    }

对于AdminReportForm.cshtml

    public ActionResult EditAdmin(int id)
    {
        var report = _context.Reports.SingleOrDefault(c => c.ID == id);
        if (report == null)
            return HttpNotFound();

        var viewModel = new UserReportViewModel
        {
            Report = report,
        };

        return View("AdminReportForm", viewModel);
    }

最后是我的帖子:

    [HttpPost]
    [ValidateInput(false)]
    public ActionResult SaveAdmin(UserReportViewModel viewModel)
    {
        if (viewModel.Report.ID == 0)
            _context.Reports.Add(viewModel.Report);
        else
            var reportInDb = _context.Reports.Single(c => c.ID == viewModel.Report.ID);

        _context.SaveChanges();
        return RedirectToAction("ReportAll", "Report");

    }

2 个答案:

答案 0 :(得分:0)

您可以将报告集合添加到视图模型吗? 然后,您可以使用linq过滤报告并填充下拉列表。

namespace BugTracker.ViewModels
{
    public class UserReportViewModel
    {
        public Report Report { get; set; }
        public List<Report> Reports {get; set;}
    }
}

答案 1 :(得分:0)

我终于能够解决此问题-谢谢大家的帮助!这是我的解决方法:

首先,在我的“ Report.cs ”文件中,添加了以下内容:

public String RelatedBugs {get; set;}
public String[] RelatedBugsArray {get; set;}

在我的视图模型“ UserReportViewModel.cs ”中,添加了以下内容:

public IEnumerable<Report> Report {get; set;}

表格给了我一些问题。我最初使用了DropDownBoxFor,但是对于多选,您实际上需要使用ListBoxFor(它仍然可以与DropDownBoxFor一起使用,但问题是当您尝试编辑表单时它无法预填充它。) > AdminReportForm.cshtml ,我有以下内容:

@Html.ListBoxFor(m => m.Report.RelatedBugsArray, new MultiSelectList(Model.Reports, "ID", "Name"), new {id = "relatedbugs"})

要使用所选脚本,我首先使用以下链接对其进行设置:Use Chosen jQuery plugin in MVC Asp Net

在同一份报告中,我使我的ListBoxFor通过以下方式使用我选择的脚本:

@section scripts{
<script>
$(function () {
$("#relatedbugs").chosen();
});
</script>
}

现在,剩下的就是控制器了。我关心两个动作:编辑和保存动作。 EditAdmin和Admin操作将具有相同的代码:

if (report.RelatedBugs != null)
     report.RelgatedBugsArray = report.RelatedBugs.Split(',');

对于SaveAdmin操作,我们只需要这样做:

if (viewModel.Report.RelatedBugsArray == null)
     viewModel.Report.RelatedBugs = null;
else
     viewModel.Report.RelatedBugs = string.Join(",", viewModel.Report.RelatedBugsArray);

基本上,我们正在做的就是将报告ID当作一个数组,并将它们放入字符串中,每个元素之间用逗号隔开。当我们将其反馈给视图时,通过在逗号之间分割每个元素,将字符串转换为数组。

再次感谢所有建议!