视图模型在asp.net mvc的 [英] ViewModel in asp.net mvc

查看:98
本文介绍了视图模型在asp.net mvc的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个使用C#中asp.net mvc的网站。我有两个型号的事件模式和票务模式。我希望能够使用附带的CRUD视图来创建一个事件,然后点击时创建的用户应该被转发到另一个页面,在这里他们可以添加门票此事件。到目前为止,我已完成了工作,所以可以创建一个事件,用户可以创建一张票。不过,我需要每个事件多票,我相信一个视图模型可能是有用的,但我不知道它是什么样子,或如何使用它,让我认为要添加多个门票。
这里是我目前的模式;

I am trying to create a asp.net mvc site using c#. I have two models an Event model and a Ticket model. I want to be able to create an Event using the supplied CRUD views and then when create is clicked the user should be forwarded to another page where they can add tickets to this event. So far I have got it working so an event can be created and the user can create one ticket. However I need multiple tickets per event so I believe a ViewModel may be useful but I've no idea what it would look like or how to use it to allow multiple tickets to be added in my view. Here are my current models;

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

这是我尝试在适当的视图模型

Here is my attempt at an appropriate viewmodel

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类

And finally here is my TicketController class

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

如果任何人都可以帮我如何可以创建事件并添加多个门票事件的所有在一个页面上或如何保存事件再创建多个票,我会非常感激,因为我一直停留在这个现在的年龄。

If anyone can help me with how to either create the event and add multiple tickets to the event all on one page or how to save the event then create multiple tickets I'd be really grateful as I've been stuck on this for ages now.

推荐答案

由于我们必须动态地添加一行新的票,我们应该用一些JavaScript来处理建筑形式和张贴。

Since we have to dynamically add a row for a new ticket, We should be using some javascript to handle the form building and posting.

有关票证创建页面创建一个视图模型

Create a viewmodel for the Ticket creation page

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

而在付诸行动,我们将创建 CreateTicketVm 的对象,设置事件属性值,并将其发送到视图。

And in the GET action, We will create an object of CreateTicketVm, Set the Event property value and send it to the view.

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添加到我们允许用户创建一个新的票行,当他们点击Add票按钮。同时,我们会听取他们对提交按钮点击事件,我们将建立一个JavaScript对象看起来一样我们的 CreateTicketVm 视图模型。我们将发布(使用AJAX)此对象的JSON版本的MVC控制器。一旦机票信息保存,操作方法将返回指示操作是否成功的JSON响应。在阿贾克斯后的完成时,我们将检查这个应答并重定向USR到下一个页面(或做一些定制的东西需要)。

Now we need to add some javascript to our allow user to create a new ticket row when they click on "Add Ticket" button. Also we will listen to the click event on the submit button and we will build a javascript object which looks same as our CreateTicketVm viewmodel. and we will post (using ajax) the json version of this object to the MVC controller. Once the ticket information is saved, The action method will return a json response which indicates whether the operation was successful. In the done event of the ajax post, we will inspect this response and redirect the usr to the next page(or do some custom thing as needed).

<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来获取每张票行的标记。因此,让我们添加一个动作方法的。

You can see that the addNewRow method is also making an ajax call to get the markup for each ticket row. So let's add an action method for that.

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

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

You can see that we are returning a partial view. So make sure to create the partial view in that location with the below content.

@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直接建立的标记。但它变得丑陋,当你的标记有更多的项目。因此,创建一个局部视图是安全的,并帮助我们需要在未来轻松地标记的变化。

We can build the markup directly in js. But it gets ugly when your markup has more items. So creating a partial view is safe and helps us to easily make markup changes as needed in future.

当用户点击提交,我们是冒充的Json版本的对象到 CreateTicket HttpPost操作方法。因此,让我们创建一个了。

When user clicks the submit, we are posing the Json version of the object to the CreateTicket HttpPost action method. So let's create that too.

[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"});
}

以上code是是Asp.Net MVC 6.在MVC 6,MVC控制器和网页API控制器不分开。他们都从控制器类,这是在 Microsoft.AspNet.Mvc 命名空间。

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

If you are using a version prior to MVC 6, You do not need the [FromBody] attribute in your HttpPost action method. Also, for returning json data, you can use Json method.

[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"});
}

这篇关于视图模型在asp.net mvc的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆