【发布时间】:2016-09-28 07:25:47
【问题描述】:
根据我上次的question 和我得到的答案,我在思考它们以及我的应用程序的真正问题是什么。而且我认为你们帮助我弄清楚了你们在那里写的所有内容,非常感谢。所以我做了一个小而有效的例子来演示我的问题:
我的模特:
public class Order
{
public int OrderID { get; set; }
public string NameOfCustomer { get; set; }
public string Address { get; set; }
}
包含我需要的另外 2 个 ViewModel 的 ViewModel:
public class ViewModelOrder
{
public ViewModelSendItNow viewModelSenditNow { get; set; }
public ViewModelSafeForLater viewModelSafeForLater { get; set; }
}
ViewModel 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 个按钮来做到这一点。问题是,该示例现在可以发送它,它会像应该的那样保存在数据库中,但是当我稍后点击安全按钮时,我得到一个空引用异常,我真的不知道为什么。所以也许你们看到了我的代码中的错误,并给我一个提示,我可以如何解决这个问题或者我可以尝试什么。
问候,
【问题讨论】:
-
你的代码没有意义。首次渲染视图时,您总是点击
else块并为viewModelSenditNow生成表单控件(因此验证将始终启动)。然后在 POST 方法中,Request.Form["SafeForLater"]将始终为null,因为您的提交按钮没有value属性,因此不回发值。那你为什么还要返回视图呢? -
@StephenMuecke 感谢您的回答。我能用语言问你一件事,你会如何解决这个问题?从概念的角度来看,有什么我完全错过了做类似的事情吗?
-
您没有提供足够的信息来解释您想要做什么,但最好的猜测是使用包含
bool SaveAsDraft属性的单一视图模型,并将 foolproof[RequiredIfFalse("SaveAsDraft")]应用于其他属性(并且可能将$.validator重新配置为仅在提交时验证)。然后如果用户想要保存可能无效的“草稿”,他们可以选中@Html.CheckBoxFor(m => m.SaveAsDraft)生成的复选框。 -
您只需要一个提交按钮,然后在POST方法中,您还可以检查
SaveAsDraft的值,如果是true,您应该将其保存到数据库中的另一个表这样主表就可以应用约束(尽管这一点实际上取决于您 - 如果您确实只有一个表,那么您的所有字段都需要允许NULL) -
再次感谢您的努力,我将尝试解释整个想法是什么。所以用户有一个像上面这样的表格,他应该能够做两件事,1)发送一个完整的订单(验证应该跳进去)2)如果他决定稍后发送完整的订单(此时没有验证),他应该能够将其保存以备后用并再次编辑。但我想将所有这些都保存在一个视图中,以便稍后他能够轻松地在真实订单和他想要稍后保存的内容之间切换。我希望现在这个想法很清楚,如果没有,请随时询问有什么不清楚的地方,我会尽力回答。
标签: c# asp.net asp.net-mvc razor model-view-controller