我已经完成了我一直在研究的这个MVC 4应用程序,但是我遇到了一些麻烦。我的应用程序的一部分包括一个向导表单,用于输入最终将插入到各自表中的数据(数据库中每个表的表单的一页)。一旦用户完成表单,他们就会被带到一个确认页面,如果他们犯了任何错误,他们可以编辑数据,如果他们没有,则点击下一步。一旦他们点击下一步,他们就会被带到一个名为“完成”的视图中,该视图显示他们已成功提交了他们的表单。当用户单击下一步以进入完整页面时,他们填写的表单中的数据应该提交到正确的数据库表。问题是,它不是这样做的。当我测试它时,我将其设置为仅将数据提交到其中一个db表,并且运行正常。但是现在我已经将其他两个表添加到了混合中,我无法让它工作。
以下是提交的控制器代码:
[HttpPost]
public ActionResult Wizard(QuotesViewModel QVM, Quote_Data quote_data, PCB_Data pcb_data, Comment comment)
{
if (ModelState.IsValid)
{
unitOfWork.Quote_Data_Repository.Insert(quote_data);
unitOfWork.Save();
unitOfWork.PCB_Data_Repository.Insert(pcb_data);
unitOfWork.Save();
unitOfWork.Comment_Repository.Insert(comment);
unitOfWork.Save();
return View("Complete", QVM);
}
return View();
}
就像我上面所说,如果我只是包括
if (ModelState.IsValid)
{
unitOfWork.Quote_Data_Repository.Insert(quote_data);
unitOfWork.Save();
return View("Complete", QVM);
}
一切正常。表单的Quote_Data部分中的数据插入时没有问题。
当我尝试在浏览器中运行应用程序时,出现以下错误:
SCRIPT5007: Unable to get property 'name' of undefined or null reference
由于jquery.validate.js中的以下代码而引发的:
idOrName: function(element) {
return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
},
以下是我的UnitOfWork和Repository类的一些相关部分
的UnitOfWork:
private StqmContext context = new StqmContext();
private GenericRepository<General_Info> general_info_repository;
private GenericRepository<Quote_Data> quote_data_repository;
private GenericRepository<PCB_Data> pcb_data_repository;
private GenericRepository<Comment> comment_repository;
public GenericRepository<General_Info> General_Info_Repository
{
get
{
if (this.general_info_repository == null)
{
this.general_info_repository = new GenericRepository<General_Info>(context);
}
return general_info_repository;
}
}
public GenericRepository<Quote_Data> Quote_Data_Repository
{
get
{
if (this.quote_data_repository == null)
{
this.quote_data_repository = new GenericRepository<Quote_Data>(context);
}
return quote_data_repository;
}
}
// same format for PCB_Data and Comment
...
public void Save()
{
context.SaveChanges();
}
GenericRepository:
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
Quote_Data_Repository(与其他存储库类的格式几乎相同)
private StqmContext context;
public Quote_Data_Repository(StqmContext context)
{
this.context = context;
}
...
public void InsertQuote_Data(Quote_Data quote_data)
{
context.Quote_Datas.Add(quote_data);
}
public void UpdateQuote_Data(Quote_Data quote_data)
{
context.Entry(quote_data).State = EntityState.Modified;
}
public void Save()
{
context.SaveChanges();
}
提前感谢任何可以提供帮助的人。
更新(2013年4月4日)
好的,所以我迄今为止所做的一切都没有提供完整的解决方案。这个向导的工作方式是,表单的每一步都放在一个并使用javascript显示或隐藏。我将在下面显示代码,但是一旦表单完成,将加载另一个名为“Confirm”的视图,其中显示用户输入的所有内容的摘要,因此如果他们犯了错误,他们可以修复它。从那里,他们可以单击下一个按钮,它将把它们带到一个页面,通知他们他们的表单已经提交,此时表单数据被放入各种数据库表中。我无法弄清楚的是,如果我摆脱了确认页面(这显然不是解决方案,因为最终结果将需要该页面),并直接跳到“完整”视图,然后提交数据没有修改[HttpPost]向导(...)控制器就像我原本想要的那样到数据库。但当我把确认页面放回去时,一切都再次崩溃。
以下是我的控制器和视图中的一些相关代码:
来自我的控制器:
[HttpGet]
public ActionResult Wizard(int id)
{
General_Info general_info = unitOfWork.General_Info_Repository.GetByID(id);
return View(new QuotesViewModel(general_info));
}
[HttpPost]
public ActionResult Wizard(Quote_Data quote_data, PCB_Data pcb_data, Comment comment)
{
if (ModelState.IsValid)
{
unitOfWork.Quote_Data_Repository.Insert(quote_data);
unitOfWork.PCB_Data_Repository.Insert(pcb_data);
unitOfWork.Comment_Repository.Insert(comment);
unitOfWork.Save();
return View("Complete");
}
return View();
}
//
// POST: /VendorForm/Confirm
[HttpGet]
public ActionResult Confirm(QuotesViewModel QVM)
{
return PartialView(QVM);
}
从我的向导视图:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function ()
{
$(".wizard-step:first").fadeIn(); // show first step
// attach backStep button handler
// hide on first step
$("#back-step").hide().click(function ()
{
var $step = $(".wizard-step:visible"); // get current step
if ($step.prev().hasClass("wizard-step")) { // is there any previous step?
$step.hide().prev().fadeIn(); // show it and hide current step
// disable backstep button?
if (!$step.prev().prev().hasClass("wizard-step")) {
$("#back-step").hide();
}
}
});
// attach nextStep button handler
$("#next-step").click(function ()
{
var $step = $(".wizard-step:visible"); // get current step
var validator = $("form").validate(); // obtain validator
var anyError = false;
$step.find("input").each(function ()
{
if (!validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
if (anyError)
return false; // exit if any error found
if ($step.next().hasClass("confirm")) { // is it confirmation?
// show confirmation asynchronously
$.post("/VendorForm/confirm", $("form").serialize(), function (r) {
// inject response in confirmation step
$(".wizard-step.confirm").html(r);
});
}
if ($step.next().hasClass("wizard-step")) { // is there any next step?
$step.hide().next().fadeIn(); // show it and hide current step
$("#back-step").show(); // recall to show backStep button
}
else { // this is last step, submit form
$("form").submit();
}
});
});
</script>
....
<div class="wizard-step">
<h3>Step Three: Additional Comments</h3>
<div class="editor-label">
Comments
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Comment.Comments)
@Html.ValidationMessageFor(model => model.Comment.Comments)
</div>
</div>
<div class="wizard-step confirm">
<!-- Loads in VendorForm/Confirm -->
</div>
从我的确认视图中:
@model SourceMvc.DAL.QuotesViewModel
@if (!ViewContext.ViewData.ModelState.IsValid)
{
<h2>The following errors were found:</h2>
@Html.ValidationSummary()
}
else
{
<h3>Please comfirm that the information you have entered is correct</h3>
<fieldset>
<legend>QuotesViewModel</legend>
<div class="display-label">
MOA
</div>
<div class="display-field">
@Html.DisplayFor(model => Model.Quote_Data.MOA)
</div>
....
<div class="display-label">
Additional Comments
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Comment.Comments)
</div>
</fieldset>
}