在 asp.net mvc 中使用 ViewModel 和局部视图
Using ViewModels and Partial View with asp.net mvc
我在创建适当的 ViewModel 以允许用户在一个视图中一次选择多张票证时遇到问题。
我有一个 Ticket 模型
public class Ticket
{
public int TicketID { get; set; }
[Required]
[ForeignKey("Event")]
//foreign key
public int EventID { get; set; }
[Required]
public string Description { get; set; }
[Required]
public float Price { get; set; }
//navigation property
public virtual Event Event { get; set; }
}
订单模型
public class Order
{
public int OrderID { get; set; }
//foreign key
[Required]
[ForeignKey("Event")]
public int EventID { get; set; }
[Required]
public DateTime OrderDate { get; set; }
[Required]
public float OrderTotal { get; set; }
public ApplicationUser user { get; set; }
public virtual Event Event { get; set; }
}
然后我有一个 OrderDetails 模型
public class OrderDetails
{
[Required]
public int OrderDetailsID { get; set; }
[Required]
//Foreign key
[ForeignKey("Order")]
public int OrderID { get; set; }
[Required]
//Foreign key
[ForeignKey("Ticket")]
public int TicketID { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string email { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
public int PhoneNumber { get; set; }
//navigation properties
public virtual Order Order { get; set; }
public virtual Ticket Ticket { get; set; }
}
我还创建了一个额外的 TicketsOrdered 模型,因为我不知道还能在哪里保存用户选择的每种门票类型的数量
public class TicketsOrdered
{
public int OrderID;
public int TicketID;
public int Quantity;
}
我想创建一个视图,显示与特定事件相关的每张门票的门票描述和价格,然后还有一个 dropdown/textbox 允许用户输入他们需要的每张门票的数量.然后我想将 TicketID、OrderID 和数量保存到我的 TicketsOrdered 数据库 table。我遇到的问题是所有数据都与这么多模型有关,我不知道如何将它们整合在一起。我完全不知道如何实现这一点,我希望它看起来如何的一个例子是当你点击 EventBrite 上的预订门票时。
任何有关 ViewModel 的帮助或如何在 View 中使用我当前的模型都会非常有帮助,谢谢。
编辑
事件模型
public class Event
{
public int EventID { get; set; }
[Required]
public String Name { get; set; }
[Required]
public String Location { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime Date { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public String Description { get; set; }
[Required]
[Display(Name = "Total Tickets Available")]
public int TicketsAvailable { get; set; }
//navigation property
public virtual IEnumerable<Order> Order { get; set; }
//navigation property
public virtual IEnumerable<Ticket> Tickets { get; set; }
}
首先创建代表您想要在视图中display/edit的视图模型
public class TicketVM
{
public int TicketID { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
public class OrderVM
{
public int ID { get; set; }
public int EventID { get; set; }
public string EventName { get; set; }
// additional properties of Event you want to display
public DateTime OrderDate { get; set; }
public string FirstName { get; set; }
// additional properties of Order and OrderDetails you want to edit
public List<TicketVM> Tickets { get; set; }
}
旁注:有点不清楚为什么 Order
和 OrderDetails
有单独的模型,或者为什么 OrderDetails
有 public int TicketID { get; set; }
,这表明 Order
只能有一张票,所以我建议您可能需要对数据库结构进行一些更改。如果意图是用户可以为不同的人订购多张票,那么每个持票人的姓名、电子邮件和 phone 可能应该存储在 TicketsOrdered
table 中(以及那些属性添加到 TicketVM
class)
然后视图将是(假设它用于 Create 方法)
@model TicketVM
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.EventID)
<h2>@Model.EventName</h2>
// other display properties of event
@Html.TextBoxFor(m => m.OrderDate)
@Html.TextBoxFor(m => m.FirstName)
// other edit control for properties of Order and OrderDetails (see note above)
@Html.EditorFor(m => m.Tickets)
<input type="submit" value="Save" />
}
和 EditorTemplate
用于 TicketVM
(在 /Views/Shared/EditorTemplates/TicketVM.cshtml
中)
@model TicketVM
@Html.HiddenFor(m => m.TicketID)
@Html.DisplayFor(m => m.Description)
@Html.DisplayFor(m => m.Price)
@Html.TextBoxFor(m => m.Quantity)
然后控制器方法将是(请注意,您没有向您展示 Event
模型,因此请调整以下内容以适应)
public ActionResult Create(int ID) // assumes ID is the ID of the Event
{
// Get the event and its tickets
Event e = db.Events.Where(e = e.EventID = ID).Include(e => e.Tickets);
// Initialize a new order
OrderVM model = new OrderVM
{
EventID = e.EventID,
EventName = e.EventName,
// other properties of event as required
Tickets = e.Tickets.Select(t => new TicketVM
{
TicketID = t.TicketID,
Description = t.Description,
Price = t.Price
})
};
return View(model);
}
[HttpPost]
public ActionResult Create(OrderVM model)
{
if (!ModelState.IsValid)
{
// repopulate any properties as required
return View(model);
}
// Initialize an Order data model, save it and gets its ID
Order order = new Order
{
OrderDate = model.OrderDate,
// other properties of Order
};
db.Orders.Add(order);
db.SaveChanges();
// ditto for OrderDetails (but see notes above)
// Initialize an TicketsOrdered data model for each valid ticket
foreach(TicketVM ticket in model.Tickets.Where(t => t.Quantity > 0))
{
TicketsOrdered ticketOrder = new TicketsOrdered
{
OrderID = order.ID,
TicketID = ticketOrder.TicketID,
Quantity = ticketOrder.Quantity
}
db.TicketsOrdered.Add(ticketOrder);
}
db.SaveChanges();
return RedirectToAction(...);
}
我在创建适当的 ViewModel 以允许用户在一个视图中一次选择多张票证时遇到问题。
我有一个 Ticket 模型
public class Ticket
{
public int TicketID { get; set; }
[Required]
[ForeignKey("Event")]
//foreign key
public int EventID { get; set; }
[Required]
public string Description { get; set; }
[Required]
public float Price { get; set; }
//navigation property
public virtual Event Event { get; set; }
}
订单模型
public class Order
{
public int OrderID { get; set; }
//foreign key
[Required]
[ForeignKey("Event")]
public int EventID { get; set; }
[Required]
public DateTime OrderDate { get; set; }
[Required]
public float OrderTotal { get; set; }
public ApplicationUser user { get; set; }
public virtual Event Event { get; set; }
}
然后我有一个 OrderDetails 模型
public class OrderDetails
{
[Required]
public int OrderDetailsID { get; set; }
[Required]
//Foreign key
[ForeignKey("Order")]
public int OrderID { get; set; }
[Required]
//Foreign key
[ForeignKey("Ticket")]
public int TicketID { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string email { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
public int PhoneNumber { get; set; }
//navigation properties
public virtual Order Order { get; set; }
public virtual Ticket Ticket { get; set; }
}
我还创建了一个额外的 TicketsOrdered 模型,因为我不知道还能在哪里保存用户选择的每种门票类型的数量
public class TicketsOrdered
{
public int OrderID;
public int TicketID;
public int Quantity;
}
我想创建一个视图,显示与特定事件相关的每张门票的门票描述和价格,然后还有一个 dropdown/textbox 允许用户输入他们需要的每张门票的数量.然后我想将 TicketID、OrderID 和数量保存到我的 TicketsOrdered 数据库 table。我遇到的问题是所有数据都与这么多模型有关,我不知道如何将它们整合在一起。我完全不知道如何实现这一点,我希望它看起来如何的一个例子是当你点击 EventBrite 上的预订门票时。 任何有关 ViewModel 的帮助或如何在 View 中使用我当前的模型都会非常有帮助,谢谢。
编辑 事件模型
public class Event
{
public int EventID { get; set; }
[Required]
public String Name { get; set; }
[Required]
public String Location { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime Date { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public String Description { get; set; }
[Required]
[Display(Name = "Total Tickets Available")]
public int TicketsAvailable { get; set; }
//navigation property
public virtual IEnumerable<Order> Order { get; set; }
//navigation property
public virtual IEnumerable<Ticket> Tickets { get; set; }
}
首先创建代表您想要在视图中display/edit的视图模型
public class TicketVM
{
public int TicketID { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
public class OrderVM
{
public int ID { get; set; }
public int EventID { get; set; }
public string EventName { get; set; }
// additional properties of Event you want to display
public DateTime OrderDate { get; set; }
public string FirstName { get; set; }
// additional properties of Order and OrderDetails you want to edit
public List<TicketVM> Tickets { get; set; }
}
旁注:有点不清楚为什么 Order
和 OrderDetails
有单独的模型,或者为什么 OrderDetails
有 public int TicketID { get; set; }
,这表明 Order
只能有一张票,所以我建议您可能需要对数据库结构进行一些更改。如果意图是用户可以为不同的人订购多张票,那么每个持票人的姓名、电子邮件和 phone 可能应该存储在 TicketsOrdered
table 中(以及那些属性添加到 TicketVM
class)
然后视图将是(假设它用于 Create 方法)
@model TicketVM
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.EventID)
<h2>@Model.EventName</h2>
// other display properties of event
@Html.TextBoxFor(m => m.OrderDate)
@Html.TextBoxFor(m => m.FirstName)
// other edit control for properties of Order and OrderDetails (see note above)
@Html.EditorFor(m => m.Tickets)
<input type="submit" value="Save" />
}
和 EditorTemplate
用于 TicketVM
(在 /Views/Shared/EditorTemplates/TicketVM.cshtml
中)
@model TicketVM
@Html.HiddenFor(m => m.TicketID)
@Html.DisplayFor(m => m.Description)
@Html.DisplayFor(m => m.Price)
@Html.TextBoxFor(m => m.Quantity)
然后控制器方法将是(请注意,您没有向您展示 Event
模型,因此请调整以下内容以适应)
public ActionResult Create(int ID) // assumes ID is the ID of the Event
{
// Get the event and its tickets
Event e = db.Events.Where(e = e.EventID = ID).Include(e => e.Tickets);
// Initialize a new order
OrderVM model = new OrderVM
{
EventID = e.EventID,
EventName = e.EventName,
// other properties of event as required
Tickets = e.Tickets.Select(t => new TicketVM
{
TicketID = t.TicketID,
Description = t.Description,
Price = t.Price
})
};
return View(model);
}
[HttpPost]
public ActionResult Create(OrderVM model)
{
if (!ModelState.IsValid)
{
// repopulate any properties as required
return View(model);
}
// Initialize an Order data model, save it and gets its ID
Order order = new Order
{
OrderDate = model.OrderDate,
// other properties of Order
};
db.Orders.Add(order);
db.SaveChanges();
// ditto for OrderDetails (but see notes above)
// Initialize an TicketsOrdered data model for each valid ticket
foreach(TicketVM ticket in model.Tickets.Where(t => t.Quantity > 0))
{
TicketsOrdered ticketOrder = new TicketsOrdered
{
OrderID = order.ID,
TicketID = ticketOrder.TicketID,
Quantity = ticketOrder.Quantity
}
db.TicketsOrdered.Add(ticketOrder);
}
db.SaveChanges();
return RedirectToAction(...);
}