HTML.DropDownListFor(...) 中的新值未在控制器 [Post] 方法中设置?

New value in HTML.DropDownListFor(...) not setting in Controller [Post] method?

希望有人能看到如何解决这个问题,因为我已经尝试了所有我能想到的方法。当我的 MVC5 应用程序中的 Create() 视图加载时,我首先在我的控制器中填充几个 [SelectList(...)](例如):

ViewBag.Model_Id = new SelectList(db.DBT_MODELS.OrderBy(x => x.MODEL_DESCRIPTION), "MODEL_ID", "MODEL_DESCRIPTION");

然后我在 Create() 视图中使用此 [SelectList(...)] 来填充 Html.DropDownListFor(...):

    <div class="form-group">
        <span class="control-label col-md-2">Model:</span>
        <div class="col-md-4">
            @Html.DropDownListFor(model => model.MODEL_ID, (SelectList)ViewBag.Model_Id, htmlAttributes: new { @class = "form-control dropdown", @id = "selectModel" })
            @Html.ValidationMessageFor(model => model.MODEL_ID, "", new { @class = "text-danger" })
        </div>
        <div class="col-md-2">
            <div class="btn-group">
                <button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
            </div>
        </div>
        <div class="col-md-4">
            <div id="createModelFormContainer" style="display:none">
                <form action="/createNewModel">
                    <input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
                    <input type="button" id="submitNewModel" value="Submit" />
                    <input type="button" id="cancelNewModel" value="Cancel" />
                </form>
            </div>
        </div>
    </div>

很简单,这一切都按预期工作。问题在于我试图合并的一些扩展功能。我的主要 class 有几个这样的属性,它们基本上是我数据库中的外键。当用户进入 Create/Edit() 我主模型中的一个实体时,我想让他们能够向这些外表添加新实体,而无需离开当前 View.

因此,我添加了(对于每个外国 属性,以 (Model) 为例)上面显示的代码,并在下面直接添加了一个按钮 Show/Hide 用户的小表格插入新值并将其添加到 DropDownList:

        <div class="col-md-2">
            <div class="btn-group">
                <button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
            </div>
        </div>
        <div class="col-md-4">
            <div id="createModelFormContainer" style="display:none">
                <form action="/createNewModel">
                    <input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
                    <input type="button" id="submitNewModel" value="Submit" />
                    <input type="button" id="cancelNewModel" value="Cancel" />
                </form>
            </div>
        </div>

我的 submitNewModel() 下面的点击事件获取用户输入的新值,然后使用 JSON 调用控制器方法将其添加到数据库 Table 中。然后 return 编辑这个新值(和它的新 ID),重置 DropDownList 的表单,我将 DropDownList 的当前值设置为新添加的值:

        $('#createNewModel').click(function () {
            $('#createModelFormContainer').show();
        })

        $('#cancelNewModel').click(function () {
            $('#createModelFormContainer').hide();
        })

        $('#submitNewModel').click(function () {
            var form = $(this).closest('form');
            var data = { description: document.getElementById('textNewModel').value };
            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("createNewModel", "INV_ASSETS")',
                data: data,
                success: function (resp) {
                    if (resp.ModelExists)
                    {
                        alert("Model [" + resp.Text + "] already exists. Please select from the DropDown.");
                    } else {
                        $('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));
                        form[0].reset();
                        $('#createModelFormContainer').hide();
                        var count = $('#selectModel option').size();
                        $('#selectModel').prop('selectedIndex', count - 1);
                        $('#selectModel').val(resp.MODEL_ID);
                        //document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [      ] once executed.
                    }
                },
                error: function () {
                    alert("ERROR - Something went wrong adding new Model [" + resp.Text + "]!");
                    $('#createModelFormContainer').hide();
                }
            });
            //reloadForNewEntity();
        });

在我的控制器中调用的createNewModel()方法:

    public JsonResult createNewModel(string description)
    {
        DBT_MODELS model = new DBT_MODELS()
        {
            // ID auto-set during save.
            MODEL_DESCRIPTION = description.Trim(),
            CREATED_DATE = DateTime.Now,
            CREATED_BY = System.Environment.UserName
        };

        var duplicateModel = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper());

        try
        {
            if (duplicateModel == null)
            {
                if (ModelState.IsValid)
                {
                    db.DBT_MODELS.Add(model);
                    db.SaveChanges();
                    // Ensure the [model.ID] is properly set after having been saved to and auto-generated in the database.
                    model.MODEL_ID = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper()).MODEL_ID;
                }
            }
            else
            {
                model = duplicateModel;
            }
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }

        return Json(new { ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION, ModelExists = (duplicateModel != null) }, JsonRequestBehavior.AllowGet);
    }

从视觉上看,到目前为止,一切都按预期进行。问题是当我去保存我是 Creating/Editing 的主要实体时。

任何已经在外部 Table 中的值,因此在视图加载时在 DropDownList 中,保存得很好;但是如果我为这些主要实体属性添加一个新的 Foreign Table 值(虽然视觉添加和当前为单个 DropDownLists 选择的值) [POST] 方法然后执行每个外部 id 值设置为 0(例如 MainClass.Model_ID =“0”与预期 MainClass.Model_ID =“625”、MainClass.Type_ID =“0”与预期 MainClass.Type_ID =“17”、MainClass.Location_ID = "0" 与预期 MainClass.Location_ID = "82" 等)

基本上,如果 Html.DropDownListFor() 中选择的值是我新添加的值之一,POST 控制器方法总是呈现所选 Html.DropDownListFor()MainClass.*_ID 值值对应为“0”。

任何人都可以告诉我如何让它工作吗?我试过:


编辑:

[已编辑 N/A]

EDIT2:干得好。谢谢大家的建议!

在您创建新模型的控制器中..您正在 return 的 json 对象是 ID, Text, ModelExists,但在您的 javascript将新 <option> 的 val 属性 重新设置为 MODEL_ID.. 这两个需要匹配..

所以把你的 javascript 改成

.val(resp.ID)

或将控制器操作中的 return 值更改为

return Json(new { MODEL_ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION

您在这里也引用了 MODEL_ID

$('#selectModel').val(resp.MODEL_ID);

所以请确保如果你不改变你的控制器操作,你也更新这个

您从操作方法返回的 json 数据采用这种格式。

{
    "ID": 24,
    "Text": "IOS",
    "ModelExists": false
}

但是在您的代码中,您正在尝试访问 resp 对象中不存在的 MODEL_ID 属性。

$('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));

更改您的代码以使用 ID 属性 值

$('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
$('#selectModel').val(resp.ID);