ASP.NET MVC:使用多视图模型以及如何将数据正确传递给模型?
问题描述:
根据我最后的question和我得到的答案,我正在考虑他们以及我的应用程序的真正问题。我想你们帮助我弄清楚了你写的所有内容,非常感谢。于是我做了一个小但工作为例来说明我的问题:ASP.NET MVC:使用多视图模型以及如何将数据正确传递给模型?
我的模型:
public class Order
{
public int OrderID { get; set; }
public string NameOfCustomer { get; set; }
public string Address { get; set; }
}
包含2周的ViewModels我所需要的视图模型:
public class ViewModelOrder
{
public ViewModelSendItNow viewModelSenditNow { get; set; }
public ViewModelSafeForLater viewModelSafeForLater { get; set; }
}
视图模型SendItNow:
public class ViewModelSendItNow
{
[Required]
public string NameOfCustomer { get; set; }
[Required]
public string Address { get; set; }
}
ViewModel SafeForLater:
public class ViewModelSafeForLater
{
public string NameOfCustomer { get; set; }
public string Address { get; set; }
}
的观点:
@model ProblemExample.Models.ViewModelOrder
@{
ViewBag.Title = "CreateOrder";
}
<h2>CreateOrder</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@if (Request.Form["SafeForLater"] != null)
{
@Html.TextBoxFor(m => m.viewModelSafeForLater.NameOfCustomer)
@Html.TextBoxFor(m => m.viewModelSafeForLater.Address)
}
else
{
@Html.TextBoxFor(m => m.viewModelSenditNow.NameOfCustomer)
@Html.TextBoxFor(m => m.viewModelSenditNow.Address)
}
<hr />
<button class="formular-button-submit" type="submit" name="SenditNow">Send it now!</button>
<button class="formular-button-submit" type="submit" name="SafeForLater">Safe it for later!</button>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
控制器:
public ActionResult CreateOrder()
{
ViewModelOrder viewModel = new ViewModelOrder();
return View(viewModel);
}
[HttpPost]
public ActionResult CreateOrder(ViewModelOrder viewModel)
{
if (Request.Form["SafeForLater"] != null)
{
Order myOrder = new Order()
{
NameOfCustomer = viewModel.viewModelSafeForLater.NameOfCustomer,
Address = viewModel.viewModelSafeForLater.Address
};
db.Orders.Add(myOrder);
db.SaveChanges();
}
else
{
Order myOrder = new Order()
{
NameOfCustomer = viewModel.viewModelSenditNow.NameOfCustomer,
Address = viewModel.viewModelSenditNow.Address
};
db.Orders.Add(myOrder);
db.SaveChanges();
}
return View(viewModel);
}
因此,用户应该看到一种形式,当他决定现在向它发送,确认应跳,如果他想要稍后保存它,不应该进行验证。这就是为什么我试图用视图中的2个按钮来做到这一点。问题是,这个例子适用于现在发送它,它会像保存在数据库中一样,但是当我点击按钮Safe以后,我得到一个Nullreference Exception,我不知道为什么。所以,也许你们看到我的代码中的错误,并给我一个提示,我可以如何解决这个问题或我可以尝试的。
问候,
答
答案很简单,因为你只渲染两个文本框在页面加载时,所以只有两个文本框会得到一个时间,这是渲染,因为它看起来Request.Form["SafeForLater"]
是空的,现在把它所以,代码移动到else块并仅渲染现在发送文本框。
你应该渲染并且只隐藏/使用css显示它们。 所以你的代码应该是这样的:
@model ProblemExample.Models.ViewModelOrder
@{
ViewBag.Title = "CreateOrder";
}
<h2>CreateOrder</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@if (Request.Form["SafeForLater"] != null)
{
@Html.TextBoxFor(m => m.viewModelSafeForLater.NameOfCustomer)
@Html.TextBoxFor(m => m.viewModelSafeForLater.Address)
<div style="display:none">
@Html.TextBoxFor(m => m.viewModelSenditNow.NameOfCustomer)
@Html.TextBoxFor(m => m.viewModelSenditNow.Address)
</div>
}
else
{
<div style="display:none">
@Html.TextBoxFor(m => m.viewModelSafeForLater.NameOfCustomer)
@Html.TextBoxFor(m => m.viewModelSafeForLater.Address)
</div>
@Html.TextBoxFor(m => m.viewModelSenditNow.NameOfCustomer)
@Html.TextBoxFor(m => m.viewModelSenditNow.Address)
}
<hr />
<button class="formular-button-submit" type="submit" name="SenditNow">Send it now!</button>
<button class="formular-button-submit" type="submit" name="SafeForLater">Safe it for later!</button>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
你的代码没有意义。当视图第一次呈现时,你总是碰到'else'块,并为'viewModelSenditNow'生成表单控件(所以验证将始终启动)。然后在POST方法中,Request.Form [“SafeForLater”]'将始终为'null',因为您的提交按钮不具有'value'属性,因此不会返回值。你为什么然后返回视图呢? –
@StephenMuecke谢谢你的回答。我可以问你一件事,用言语来说,你会如何解决这个问题?从概念的角度来看,我是否完全错过了做这样的事情? – RawMVC
你没有给出足够的信息来解释你想要做什么,但最好的猜测是使用单一的视图模型,其中包含一个'bool SaveAsDraft'属性,并应用一个[万无一失](http://foolproof.codeplex.com /)'[RequiredIfFalse(“SaveAsDraft”)]'到其他属性(并可能重新配置'$ .validator'只在提交时验证)。然后,如果用户想要保存可能无效的“草稿”,他们可以检查由“@ Html.CheckBoxFor(m => m.SaveAsDraft)''生成的复选框。 –