ViewModel in asp.net mvc

本文关键字:mvc net asp in ViewModel | 更新日期: 2023-09-27 18:25:28

我正在尝试使用c#创建一个asp.net mvc网站。我有两个模型——Event模型和Ticket模型。我希望能够使用提供的CRUD视图创建Event,然后当单击创建时,用户应该被转发到另一个页面,在那里他们可以为该事件添加票证。到目前为止,我已经让它工作了,这样就可以创建一个事件,用户可以创建一张票。然而,我需要每个活动多张门票,所以我相信ViewModel可能很有用,但我不知道它会是什么样子,也不知道如何使用它来允许在我的视图中添加多张门票。以下是我目前的型号;

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.Time)]
    public DateTime StartTime { get; set; }
    [Required]
    [DataType(DataType.MultilineText)]
    public String Description { get; set; }
    [Required]
    public int TicketsAvailable { get; set; }
    //navigation property
    public virtual ICollection<Order> Order { get; set; }
    //navigation property
    public virtual ICollection<Ticket> Ticket { get; set; }
}    
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; }
    //navigation property
    public ICollection<OrderDetails> OrderDetails { get; set; }
}

这是我尝试的一个合适的视图模型

public class EventTicketViewModel
{
    public Event events {get; set;}
    public List<Ticket> tickets { get; set; }
}    

这是我创建的票证视图

@model GeogSocSite.Models.Ticket
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
    <h4>Ticket</h4>
    <hr />
    @Html.HiddenFor(model => model.EventID)
    <div class="form-group">
        @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>

最后是我的TicketController类

public class Tickets1Controller : Controller
{
    private ApplicationDbContext db = new ApplicationDbContext();
    private TicketRepository _ticketRepository;
    public Tickets1Controller()
    {
        this._ticketRepository = new TicketRepository();
    }
    // GET: Tickets
    [AllowAnonymous]
    public ActionResult Index()
    {
        return View(_ticketRepository.GetTickets());   
    }
    // GET: Tickets1/Details/5
    [AllowAnonymous]
    public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Ticket ticket = _ticketRepository.GetByID(id);
        if (ticket == null)
        {
            return HttpNotFound();
        }
        return View(ticket);
    }
    // GET: Tickets1/Create
    [AllowAnonymous]
    public ActionResult Create(int id)
    {
        Ticket ticket = new Ticket();
        ticket.EventID = id;
        return View(ticket);
    }
    // POST: Tickets1/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    [AllowAnonymous]
    public ActionResult Create([Bind(Include = "TicketID,EventID,Description,Price")] Ticket ticket)
    {
        if (ModelState.IsValid)
        {
            _ticketRepository.InsertTicket(ticket);
            _ticketRepository.Save();
            return RedirectToAction("Index");
        }
        return View(ticket);
    }
    // GET: Tickets1/Edit/5
    [AllowAnonymous]
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Ticket ticket = _ticketRepository.GetByID(id);
        if (ticket == null)
        {
            return HttpNotFound();
        }
        return View(ticket);
    }
    // POST: Tickets1/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    [AllowAnonymous]
    public ActionResult Edit([Bind(Include = "TicketID,EventID,Description,Price")] Ticket ticket)
    {
        if (ModelState.IsValid)
        {
            _ticketRepository.UpdateTicket(ticket);
            return RedirectToAction("Index");
        }
        return View(ticket);
    }
    // GET: Tickets1/Delete/5
    [AllowAnonymous]
    public ActionResult Delete(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Ticket ticket = _ticketRepository.GetByID(id);
        if (ticket == null)
        {
            return HttpNotFound();
        }
        return View(ticket);
    }
    // POST: Tickets1/Delete/5
    [HttpPost, ActionName("Delete")]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        _ticketRepository.DeleteTicket(id);
        _ticketRepository.Save();
        return RedirectToAction("Index");
    }
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
}

如果有人能帮助我创建活动并在一个页面上添加多张活动门票,或者如何保存活动并创建多张门票,我将不胜感激,因为我已经在这方面做了很长时间了。

ViewModel in asp.net mvc

由于我们必须为新票据动态添加一行,我们应该使用一些javascript来处理表单构建和发布。

为票证创建页面创建视图模型

public class CreateTicketVm
{
    public int EventId { get; set; }
    public List<TicketVm> Tickets { set; get; }
}
public class TicketVm
{
    [Required]
    public string Description { get; set; }
    [Required]
    public float Price { get; set; }
}

在GET操作中,我们将创建一个CreateTicketVm对象,设置Event属性值并将其发送到视图。

public ActionResult CreateTicket(int id)
{
    var vm = new CreateTicketVm {EventId = id};       
    return View(vm);
}

在你看来

@model YourNamespace.CreateTicketVm
<div id="tickets"></div>
@Html.HiddenFor(s => s.EventId)
<input type="button" id="add" value="Add Ticket" />
<input type="submit" id="btnSave" />

现在,我们需要添加一些javascript到我们的允许用户在单击"添加票证"按钮时创建一个新的票证行。此外,我们将听取提交按钮上的点击事件,并构建一个与CreateTicketVm视图模型相同的javascript对象。我们将(使用ajax)这个对象的json版本发布到MVC控制器。一旦票证信息被保存,action方法将返回一个json响应,指示操作是否成功。在ajax文章的done事件中,我们将检查此响应并将usr重定向到下一页(或者根据需要进行一些自定义操作)。

<script>
    $(function () {
       //Lets create the first row
        addNewRow();
        $("#add").click(function (e) {
            e.preventDefault();
            addNewRow();    
        });
        $("#btnSave").click(function (e) {
            e.preventDefault();
            var createTicket = { EventId: $("#EventId").val(), Tickets: [] };
            var rows = $("#tickets").find(".item");
            $.each(rows, function (i, row) {
                var _row = $(this);
                var inputs = _row.find("input");
                var ticket = {};
                $.each(inputs, function (index, item) {
                    var _this = $(this);
                    ticket[_this.data("for")] = _this.val();
                });
                createTicket.Tickets.push(ticket);
            });
            var targetUrl = "@Url.Action("CreateTicket","Home")";
            $.ajax({
                url: targetUrl,
                contentType: "application/json",
                data: JSON.stringify(createTicket),
                type: "POST"
            }).done(function(res) {
                if (res.Status === "Success") {
                    window.location.href = "@Url.Action("Success")";
                }
            });
        });
    });
    function addNewRow() {          
        $.get("@Url.Action("AddNewTicketRow","Home")", function (res) {    
            $("#tickets").append(res);    
        });    
    }
</script>

您可以看到,addNewRow方法还进行了ajax调用,以获取每个票证行的标记。因此,让我们添加一个操作方法。

public ActionResult AddNewTicketRow()
{
    var vm = new TicketVm ();
    return PartialView("~/Views/Home/Partials/AddNewTicketRow.cshtml", vm);
}

您可以看到,我们正在返回部分视图。因此,请确保在该位置创建具有以下内容的局部视图。

@model TicketVm
<div class="item">
    @Html.TextBoxFor(s => s.Description, new {@data_for = "Description"}) 
    Price : @Html.TextBoxFor(s=>s.Price, new {@data_for="Price"})
</div>

我们可以直接在js中构建标记。但是,当您的标记包含更多项目时,它会变得很难看。因此,创建局部视图是安全的,可以帮助我们在将来根据需要轻松地进行标记更改。

当用户单击提交时,我们将向CreateTicket HttpPost操作方法提出对象的Json版本。所以,让我们也创造它。

[HttpPost]
public ActionResult CreateTicket([FromBody] CreateTicketVm model)
{
    if (model != null)
    {
       //check model.Tickets and model.EventId
       // to do : Save Tickets for the event
        return new JsonResult( new { Status ="Success"});
    }
    return new JsonResult( new { Status ="Error"});
}

上面的代码是针对Asp的。Net MVC 6。在MVC 6中,MVC控制器和Web-Api控制器不是分开的。它们都继承自Microsoft.AspNet.Mvc命名空间中的Controller类。

如果您使用的是MVC 6之前的版本,则在HttpPost操作方法中不需要[FromBody]属性。此外,对于返回json数据,可以使用Json方法。

[HttpPost]
public ActionResult CreateTicket(CreateTicketVm model)
{
    if (model != null)
    {
        //check model.Tickets and model.EventId
        // to do : Save Tickets for the event
        return Json(new {Status = "Success"});
    }
    return Json(new {Status = "Error"});
}