【问题标题】:Using ViewModels and Partial View with asp.net mvc在 asp.net mvc 中使用 ViewModels 和 Partial View
【发布时间】:2016-01-10 16:54:18
【问题描述】:

我在创建适当的 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;
}

我想创建一个视图,该视图将显示与特定活动相关的每张门票的门票描述和价格,然后还会有一个下拉/文本框允许用户输入他们需要的每张门票的数量。然后我想将 TicketID、OrderID 和数量保存到我的 TicketsOrdered 数据库表中。我遇到的问题是所有数据都与这么多模型有关,我不知道如何将它们组合在一起。我完全不知道如何实现这一点,我希望它看起来如何的一个例子是当你点击 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; }

}

【问题讨论】:

  • 您声明与特定活动相关的每张门票,但您的模型建议您每个活动只有一张门票,而不是门票的集合。你的Event 型号是什么?它是否包含属性IEnumerable&lt;Order&gt;
  • 是的,我有一个包含 IEnumerable @StephenMuecke 的事件模型。我需要更改哪种模型以显示每个活动可以有多张门票?谢谢
  • 目前还不清楚你们的关系是什么。每个Event 是否也有不同Ticket 类型的集合?并且是您想要为Event 创建一个Order 的想法,该Event 显示该Event 的所有可用票类型,并允许用户为每个输入数量(假设他们想要2 张标准票和2 张豪华票票)?
  • 是的,这正是我想要做的@StephenMuecke
  • 好的 - 现在没时间了,但我会在一小时左右添加一个答案,展示视图模型和视图应该是怎样的。另请注意,不清楚为什么 OrderOrderDetails 有单独的模型,因为它们之间似乎存在 1:1 的关系

标签: c# jquery html asp.net-mvc viewmodel


【解决方案1】:

首先创建代表您想要在视图中显示/编辑的视图模型

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; }
}

旁注:有点不清楚为什么OrderOrderDetails 有单独的模型,或者为什么OrderDetailspublic int TicketID { get; set; },这表明Order 只能有一张票,所以我建议你可能需要对您的数据库结构进行一些更改。如果意图是用户可以为不同的人订购多张门票,那么每个持票人的姓名、电子邮件和电话可能应该存储在TicketsOrdered 表中(以及添加到TicketVM 类中的那些属性)

然后视图将是(假设它用于 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(...);
}

【讨论】:

  • 谢谢@StephenMuecke。当我说我的事件模型中有 IEnnumerable 时,我犯了一个错误。然后现在当我将它添加到模型中时,我不知道如何向它添加票证。我更新了我的帖子以包含事件模型。我尝试将 IEnnumerable 更改为 IList,以便我可以使用 Add 方法,但这引发了有关此行的异常 Tickets = e.Tickets.Select(t => new TicketVm {
  • 看不到Event 模型的任何更新。但是,如果它不包含门票的集合属性,那么您可以使用 Tickets = db.Tickets.Where(t =&gt; t.EventID = ID).Select(t =&gt; new TicketVM { TicketID = t.TicketID, Description = t.Description, Price = t.Price }) 之类的东西填充 OrderVM。但正如我之前提到的,我怀疑您的数据库设计可能存在一些问题
  • 太好了,非常感谢您的所有帮助,非常感谢您抽出宝贵时间帮助我@StephenMuecke!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 2019-06-11
  • 2019-03-07
相关资源
最近更新 更多