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”。
任何人都可以告诉我如何让它工作吗?我试过:
- 更改我的 JavaScript 在 JSON 调用我的控制器操作 return 之后在 DropDownList 中设置值的方式(示例):
//document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed.
vs $('#selectModel').val(resp.MODEL_ID);
在 DropDownList 中直观地呈现预期的新值。
- 在 Controller 方法的 return 上,设置一个新的 ViewBag 变量,然后希望在 POST 方法中引用保存的值(没有用,JavaScript 呈现了我的
@Viewbag.PostModelID = resp.ModelID
为“= resp.ModelID”并抛出许多预期的错误)。
编辑:
[已编辑 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);
希望有人能看到如何解决这个问题,因为我已经尝试了所有我能想到的方法。当我的 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”。
任何人都可以告诉我如何让它工作吗?我试过:
- 更改我的 JavaScript 在 JSON 调用我的控制器操作 return 之后在 DropDownList 中设置值的方式(示例):
//document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed.
vs$('#selectModel').val(resp.MODEL_ID);
在 DropDownList 中直观地呈现预期的新值。 - 在 Controller 方法的 return 上,设置一个新的 ViewBag 变量,然后希望在 POST 方法中引用保存的值(没有用,JavaScript 呈现了我的
@Viewbag.PostModelID = resp.ModelID
为“= resp.ModelID”并抛出许多预期的错误)。
编辑:
[已编辑 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);