无法在代码优先实体框架

时间:2017-07-16 16:38:54

标签: c# entity-framework model-view-controller

我是MVC的新手,为noob问题道歉!

我有以下模型(TimeEntry),用于输入时间表详细信息:

namespace MVCLogin.Models
{
    public class TimeEntry
    {
        public int TimeEntryID { get; set; }
        public int TaskTypeID { get; set; }
        [ForeignKey("TaskTypeID")]
        public virtual TaskType TaskType { get; set; }
        public double MonHours { get; set; }
        public double TueHours { get; set; }
        public double WedHours { get; set; }
        public double ThuHours { get; set; }
        public double FriHours { get; set; }

    }
}

任务类型基于以下模型:

namespace MVCLogin.Models
{
    public class TaskType
    {
        public int TaskTypeID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
}

我使用以下部分视图来输入时间表详细信息:

<div class="col-md-1">
    @Html.EditorFor(model => model.TaskType)
    @Html.ValidationMessageFor(model => model.TaskType)
</div>
<div class="col-sm-1">
    @Html.TextBoxFor(model => model.MonHours , new { style = "width:100%", @class = "hours mon" })
    @Html.ValidationMessageFor(model => model.MonHours)
</div>
<div class="col-sm-1">
    @Html.TextBoxFor(model => model.TueHours, new { style = "width:100%", @class = "hours tue" })
    @Html.ValidationMessageFor(model => model.TueHours)
</div>
<div class="col-sm-1">
    @Html.TextBoxFor(model => model.WedHours, new { style = "width:100%", @class = "hours wed" })
    @Html.ValidationMessageFor(model => model.WedHours)
</div>
<div class="col-sm-1">
    @Html.TextBoxFor(model => model.ThuHours, new { style = "width:100%", @class = "hours thu" })
    @Html.ValidationMessageFor(model => model.ThuHours)
</div>
<div class="col-sm-1">
    @Html.TextBoxFor(model => model.FriHours, new { style = "width:100%", @class = "hours fri" })
    @Html.ValidationMessageFor(model => model.FriHours)
</div>

我希望任务类型字段是下拉列表,但我无法弄清楚如何连接它。类和数据是正确的,就像我为TimeEntry类构建一个控制器(使用Visual Studio的Add Controller工具),它工作正常:

<div class="form-group">
    @Html.LabelFor(model => model.TaskTypeID, "TaskTypeID", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownList("TaskTypeID", null, htmlAttributes: new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.TaskTypeID, "", new { @class = "text-danger" })
    </div>
</div>

enter image description here

如何让下拉列表在局部视图中工作?

2 个答案:

答案 0 :(得分:1)

Html.DropDownList中的null参数是Dropdown的数据,而且是Ienumerable<SelectList>

为了传递数据。您需要将TaskType列表转换为SelectListItem列表(您可以在控制器之前或在将模型从Controller发送到View之前的其他位置执行此操作)并将其放入模型中,如此

namespace MVCLogin.Models
{
    public class TimeEntry
    {
        public int TimeEntryID { get; set; }
        public int TaskTypeID { get; set; }
        [ForeignKey("TaskTypeID")]
        public virtual TaskType TaskType { get; set; }
        public IEnumerable<SelectListItem> TaskTypeSelectListItems { get; set; }
        public double MonHours { get; set; }
        public double TueHours { get; set; }
        public double WedHours { get; set; }
        public double ThuHours { get; set; }
        public double FriHours { get; set; }

    }
}

下拉代码将更改为

<div class="form-group">
    @Html.LabelFor(model => model.TaskTypeID, "TaskTypeID", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownList("TaskTypeID", model => model.TaskTypeSelectListItems, htmlAttributes: new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.TaskTypeID, "", new { @class = "text-danger" })
    </div>
</div>

请注意,当您发布/到达服务器时,所选值将绑定到模型上的“TaskTypeID”。

答案 1 :(得分:1)

根据您的要求:因此ViewBag是一个属性,使您可以动态地将控制器中的值共享到视图中。由于它是动态的,请记住,您需要显式转换对象,以便剃刀引擎知道它们在运行时是什么。请注意,在阅读它时(在底部进一步阅读),ViewBag是短暂的,只存在于当前请求中,因此如果控制器中存在模型状态错误,则需要将数据重新加载到viewbag中。

这有助于保持模型/视图模型非常干净。

所以关于代码,测试设置:我有我的主页面(索引),我有一个部分视图(AddSomething),它加载在我的主索引页面中。鉴于您的模型,这是我的控制器的样子。请注意,我最初在父页面中加载了视图包,但如果我的提交发生错误,那么我需要重新加载我的视图包,因为动态对象是短暂的。

    DALHelper dalHelp = new DALHelper();

    public ActionResult Index()
    {
        //Get a list of task types from the data access layer
        //Cast them into a SelectItemList and pass them into viewBag
        ViewBag.TaskDD = dalHelp.GetTaskTypes().Select(a => new SelectListItem { Text = a.Name, Value = a.TaskTypeID.ToString() }).ToList();
        return View();
    }

    public ActionResult AddSomething()
    {
        TimeEntry te = new TimeEntry();
        return View(te);
    }

    [HttpPost]
    public ActionResult AddSomething(TimeEntry te)
    {

        if (ModelState.IsValid)
        {
            //call my Data Access Layer to add new entry and redirect to wherver on success 
            if (dalHelp.CreateTimeEntry(te))
            {
                return RedirectToAction("Index");
            }
            else
            {
                //something happened during adding entry into DB, write whatever code to handle it gracefully
                //I need to reload my viewbag since it has since been cleared (short lived)
                ViewBag.TaskDD = dalHelp.GetTaskTypes().Select(a => new SelectListItem { Text = a.Name, Value = a.TaskTypeID.ToString() }).ToList();
                ModelState.AddModelError("TimeEntryID", "An Error was encountered...");
                return View(te);
            }
        }
        else
        {
            //I need to reload my viewbag since it has since been cleared (short lived)
            ViewBag.TaskDD = dalHelp.GetTaskTypes().Select(a => new SelectListItem { Text = a.Name, Value = a.TaskTypeID.ToString() }).ToList();
            return View(te);
        }
    }

在我的局部视图中,我需要投射我的viewbag项目,因为它是一个动态类型,所以剃刀引擎可以处理:也不是我使用Dropdownlist而不仅仅是下拉列表:

    @model deletemeweb2.Models.TimeEntry

    @using (Html.BeginForm("AddSomething", "Home")) 
    {
        @Html.AntiForgeryToken()

        <div class="form-horizontal">
            <h4>TimeEntry</h4>
            @Html.ValidationMessageFor(model => model.TimeEntryID, "", new { @class = "text-danger" })

            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-group">
                @Html.LabelFor(model => model.TaskTypeID, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownListFor(model => model.TaskTypeID, (IEnumerable<SelectListItem>)ViewBag.TaskDD, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.TaskTypeID, "", new { @class = "text-danger" })
                </div>
            </div>

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

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

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

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

            <div class="form-group">
                @Html.LabelFor(model => model.FriHours, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.FriHours, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.FriHours, "", 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>
    }

在处理不同的控制器需求时,进一步阅读有关ViewBag和类似属性的内容:http://www.c-sharpcorner.com/blogs/viewdata-vs-viewbag-vs-tempdata-in-mvc1