私はコントローラとビューを使用して、ユーザーがショッピングカートの内容を「チェックアウト」できるようにしています。ViewModelがPOSTで更新されない
CheckoutControllerがOrderモデルをCheckoutビューに戻していたとき、すべて正常に機能していました。しかし、Checkoutビューにショッピングカートの内容を表示したいので、OrderとCartItemを含むビューモデルを使用するようにControllerとViewを変更しました。
私はCheckoutViewModelを作成し、このviewmodelを使用するためにGET:およびPOST:ActionResultsを変更しました。
問題はCheckOutViewModelが正しくPOST中に移入されていないです。
私はこの行のエラー「checkoutViewModel.Order.Username =ユーザー「オブジェクトのインスタンスに設定されていないオブジェクト参照」を取得しています。 Identity.Name; ' POST:ActionResultでは、しかし、私は何がinstansiatedされていない正確にはわかりません。
必要な場合は、CheckoutViewModelの代わりにOrederモデルを使用したオリジナルのコードを投稿することができます。
私はいくつかの単純な構造や構文の問題があると確信していますが、私はMVCの中で最良の方法で頭を尽くそうとしているからです。
GET:のActionResult
//GET: /Checkout/AddressAndPayment
public ActionResult AddressAndPayment()
{
//To pre-populate the form, create a new Order object and get the ShoppingCart, populate the ViewModel and pass it to the view
var order = new Order();
order.Username = User.Identity.Name;
MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
storeDB.SaveChanges();
var cart = ShoppingCart.GetCart(this.HttpContext);
// Set up our ViewModel
var viewModel = new CheckoutViewModel
{
CartItems = cart.GetCartItems(),
CartTotal = cart.GetTotal(),
Order = order
};
// Return the view
return View(viewModel);
}
POST:のActionResult
//POST: /Checkout/AddressAndPayment
[HttpPost]
public ActionResult AddressAndPayment(FormCollection values)
{
var checkoutViewModel = new CheckoutViewModel();
TryValidateModel(checkoutViewModel);
try
{
checkoutViewModel.Order.Username = User.Identity.Name;
checkoutViewModel.Order.OrderDate = DateTime.Now;
//Save Order
storeDB.Orders.Add(checkoutViewModel.Order);
storeDB.SaveChanges();
//Process the order
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.CreateOrder(checkoutViewModel.Order);
storeDB.SaveChanges();
//Send 'Order Confirmation' email
ViewData["order"] = checkoutViewModel.Order;
UserMailer.OrderConfirmation(checkoutViewModel.Order).SendAsync();
return RedirectToAction("Complete", new { id = checkoutViewModel.Order.OrderID });
}
catch
{
//Invalid - redisplay with errors
return View(checkoutViewModel);
}
}
あなたはUはずビュー
@model OrderUp.ViewModels.CheckoutViewModel
@{
ViewBag.Title = "AddressAndPayment";
}
<script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<h2>Pick Up Details</h2>
<fieldset>
<legend>When are you gonna be hungry?</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Order.Phone)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Order.Phone)
@Html.ValidationMessageFor(model => model.Order.Phone)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Order.PickUpDateTime)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Order.PickUpDateTime)
@Html.ValidationMessageFor(model => model.Order.PickUpDateTime)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Order.Notes)
</div>
<div class="editor-multiline-field">
@Html.EditorFor(model => model.Order.Notes)
@Html.ValidationMessageFor(model => model.Order.Notes)
</div>
</fieldset>
<input type="submit" value="Submit Order" />
}
<div style="height:30px;"></div>
<h3>
<em>Review</em> your cart:
</h3>
<table>
<tr>
<th>
Menu Item
</th>
<th>
Price (each)
</th>
<th>
Notes
</th>
<th>
Quantity
</th>
<th></th>
</tr>
@foreach (var item in Model.CartItems)
{
<tr id="[email protected]">
<td>
@Html.ActionLink(item.MenuItem.Name, "Details", "Store", new { id = item.MenuItemID }, null)
</td>
<td>
@Html.DisplayFor(modelItem => item.MenuItem.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.Notes)
</td>
<td id="[email protected]">
@item.Count
</td>
<td>
</td>
</tr>
}
<tr>
<td >
Total
</td>
<td id="cart-total">
@String.Format("${0:F2}", Model.CartTotal)
</td>
<td>
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
私はあなたのデータベースに2つの別々のセーブをしているので、ここでは小さな変更を提案します - トランザクションでそれらをラップするため、2番目のセーブが失敗した場合は全メソッドをロールバックし、一貫性のない状態。 –