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

时间:2015-12-03 16:02:49

标签: asp.net-mvc entity-framework razor asp.net-mvc-5 html.dropdownlistfor

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

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

然后我在创建()视图中使用此[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>

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

因此,我添加了(对于每个外国财产,使用(模型)作为示例)上面显示的代码,并在下面再次使用按钮显示/隐藏小表单,以便用户插入新值并拥有它添加到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调用将其添加到数据库表中。然后返回这个新值(以及它的新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);
    }

从视觉上讲,到目前为止,一切都按预期进行。问题是当我去保存主要实体我正在创建/编辑。

在外表中已经存在的任何值,因此在View加载时的DropDownList中,保存得很好;但是如果我为这些主要实体属性添加新的外部表值(虽然可视地添加了各个DropDownLists的当前选定值),然后执行[POST]方法,并将每个外部id值设置为0(例如,MainClass.Model_ID =&#34; 0&#34; vs期望MainClass.Model_ID =&#34; 625&#34;,MainClass.Type_ID =&#34; 0&#34; vs期望MainClass.Type_ID =&#34 ; 17&#34;,MainClass.Location_ID =&#34; 0&#34; vs期望MainClass.Location_ID =&#34; 82&#34;等。)

基本上,如果Html.DropDownListFor()中选择的值是我新添加的值之一,则POST控制器方法始终呈现所选MainClass.*_ID值对应的Html.DropDownListFor()值as&#34; 0&#34;。

有谁能指出我如何使这个工作?我试过了:

  • 在对控制器操作的JSON调用之后更改我的JavaScript在DropDownList中设置值的方式返回(ex)://document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed. vs $('#selectModel').val(resp.MODEL_ID);,它可视地呈现DropDownList中的预期新值。 / LI>
  • 从Controller方法返回时,设置一个新的ViewBag变量,然后希望在POST方法中引用保存的值(不起作用,JavaScript将@Viewbag.PostModelID = resp.ModelID渲染为&#34; = resp.ModelID& #34;并抛出了许多预期的错误。)

修改

[N / A编辑]

EDIT2 :很高兴。谢谢大家的建议!

2 个答案:

答案 0 :(得分:1)

您从操作方法返回的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);

答案 1 :(得分:0)

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

因此,将您的javascript更改为

MODEL_ID

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

.val(resp.ID)

您还在这里引用return Json(new { MODEL_ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION

MODEL_ID

因此,如果您不更改控制器操作,请同时更新