У меня есть контроллер и просмотр, которые позволяют пользователю «проверять» содержимое корзины покупок.ViewModel не обновляется на POST
Все отлично работало, когда мой CheckoutController возвращал модель заказа в представление Checkout. Однако теперь я хочу также отображать содержимое корзины покупок в представлении «Копить», поэтому изменил «Контроллер» и «Вид», чтобы использовать модель просмотра, содержащую Order и CartItems.
Я создал CheckoutViewModel и изменил GET: и POST: ActionResults, чтобы использовать эту модель.
Проблема является CheckOutViewModel не должным образом заполняется во время процедуры POST:
Я получаю «ссылка на объект не указывает на экземпляр объекта» ошибки на этой линии «checkoutViewModel.Order.Username = User. Identity.Name;» в POST: ActionResult, но я точно не знаю, что не создается.
Если нужно, я могу опубликовать исходный рабочий код, который использовал модель Oreder вместо CheckoutViewModel.
Уверен, что у меня есть простая проблема со степенью или синтаксисом, я просто не могу сказать, что это такое, потому что я все еще пытаюсь найти лучший способ сделать что-то в 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);
}
}
Посмотреть
@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 отдельными сохраняет в вашу БД - Для того, чтобы обернуть их в сделке, так что если второй бросок терпит неудачу всего метод может откатить и не оставить дб в несогласованное состояние. –