我创建了一个MVC5应用程序,它是由我的模型通过脚手架生成的视图和控制器, 在模型中,我有一个dev和prod的下拉列表工作正常,我已经验证了 对于字母数字的名称,问题是例如用户选择产品(第二个 选项)并在名称字段中输入错误数据并按Enter键,视图将刷新 下拉列表将选择从prod更改为dev。我怎么能避免这种情况?
如何在视图中询问类型是否与dev不同,如果是,则将所选项目放入?
型号:
public class Ad
{
public int ID { get; set; }
[RegularExpression(@"^[a-zA-Z0-9]*$", ErrorMessage = "Invalid Name")]
public string Name { get; set; }
public IEnumerable<SelectListItem> Type
{
get
{
return new[]
{
new SelectListItem {Value = "D", Text = "Dev"},
new SelectListItem {Value = "p", Text = "Prod"}
};
}
}
查看:
<div class="form-group">
@Html.LabelFor(model => model.SystemType, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.Type, Model.Type)
</div>
</div>
编辑创建操作
@model WebApplication3.Models.Ad
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
debugger;
$('select[name="Type"]').change(function () {
if ($(this).val() === 'p') {
$('input[name="User"]').prop("disabled", true);
$('input[name="Password"]').prop("disabled", true);
}
else {
$('input[name="User"]').prop("disabled", false);
$('input[name="Password"]').prop("disabled", false);
}
});
});
</script>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Ad</h4>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Type, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.Type, Model.Type)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.User, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.User)
@Html.ValidationMessageFor(model => model.User)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
</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>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
public class AdController : Controller
{
private AdDBContext db = new AdDBContext();
public ActionResult Index()
{
return View(db.Ad.ToList());
}
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Ad ad = db.Ad.Find(id);
if (ad == null)
{
return HttpNotFound();
}
return View(ad);
}
public ActionResult Create()
{
return View( new Ad());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="ID,Name,User,Password")] Ad ad)
{
if (ModelState.IsValid)
{
db.Ad.Add(ad);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ad);
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Ad ad = db.Ad.Find(id);
if (ad == null)
{
return HttpNotFound();
}
return View(ad);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Name,User,Password")] Ad ad)
{
if (ModelState.IsValid)
{
db.Entry(ad).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ad);
}
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Ad ad = db.Ad.Find(id);
if (ad == null)
{
return HttpNotFound();
}
return View(ad);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Ad ad = db.Ad.Find(id);
db.Ad.Remove(ad);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
答案 0 :(得分:1)
在下拉列表更改事件中,在隐藏字段中写入所选选项值,并在刷新页面时从隐藏字段中获取值,并从操作中设置所选项目。
$('select#Type').change(function(){
$('#selectedOne').val($(this).val());
});
并在您的操作中从FormCollection中读取并设置SelectList的选定项目
在视图中创建隐藏字段:
<div class="form-group">
@Html.LabelFor(model => model.SystemType, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.Type, Model.Type)
<input type="hidden" id="selectedOne" vlaue="" name="selectedOne" />
</div>
</div>
在你的行动中:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="ID,Name,User,Password")] Ad ad,FormCollection form)
{
string selectedValue = form["selectedOne"].ToString();
if (ModelState.IsValid)
{
db.Ad.Add(ad);
db.SaveChanges();
return RedirectToAction("Index");
}
foreach(var item in ad.Type)
{
if(item.Value == selectedValue)
{
item.Selected = true;
}
}
return View(ad);
}
解决方案2:
另一个简单的解决方案是使用@Ajax.BeginForm
Hepler而不是@Html.BeginForm
,以便通过ajax发布表单,并且您的下拉列表不会被重置。