2

I'm fairly new to ASP.NET MVC. The idea is very straightforward, but I can't seem to make it work.

I have a "ticket", which can be viewed under /Tickets/Details/[id]. Underneath this ticket is a list of comments and a "add comment" section. In the beginning I tested it all separately and manually wrote the TicketID. Now I need to save the current ticket's id and the whole ticket in this comment for later use. After the comment is successfully saved the page (of the ticket) should be refreshed.

Based on previous experience in ASP I tried this underneath my ticket details

<div class="panel panel-info">
<div class="panel-heading">Comments</div>
<div class="panel-body">
    @{
        Html.RenderAction("create", "TicketComments");
    }
</div>

I tried the following thing in my TicketCommentsController.cs:

    public ActionResult Create([Bind(Include = "ID, body")] TicketComment ticketComment)
    {
        Ticket ticket = db.Tickets.Find(ticketComment.ID);

        if (ModelState.IsValid)
        {
            ticketComment.UserID = User.Identity.GetUserId();
            ticketComment.AanmaakDateTime = DateTime.Now.ToLocalTime();
            ticketComment.UpdateDateTime = DateTime.Now.ToLocalTime();
            ticketComment.ParentTicketId = ticket.ID;
            ticketComment.ParentTicket = ticket;
            db.TicketComments.Add(ticketComment);
            db.SaveChanges();

            return View(ticket);
        }

        return View(ticket);
    }

but on the return it gives me an excpetion:

"The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.Ticket_5309A05301E0FE6AD5614FE3ED9E54D6FAB46DFEAFB2A38B4341FACD04441DF5', but this dictionary requires a model item of type 'Cronos.Models.TicketComment'."

I'm confused on what to do next. One thing I read was merge the TicketCommentsController in TicketsController, but this feels messy.

Can anyone help?

2 Answers2

0

I suggest you post what the view is. According to the exception message, you could only pass a

TicketComment

to your view (Check the first line, it should be @model Cronos.Models.TicketComment which defines the model in this view)

you passed Ticket instead to that view.

Jibei Zhao
  • 31
  • 5
  • I see what you mean. It took me a while to realize, but when I left the return view empty it went through the Create.cshtml of the TicketComments views. I thought the return value would go to the details page of the specific ticket. I do end up back on the page, but the textbox for the comment is filled. any idea if this is the correct way to refresh the page after the comment is saved? – Rachelle Janssen Nov 08 '16 at 20:31
0

The view expects a TicketComment instead you send the Ticket proxy and it used the default Create view.

Instead of

return View(ticket);

Redirect on a successful save and let the details action look up and display its own model. The PRG pattern.

[HttpPost]
public ActionResult Create([Bind(Include="ID, comments")] ticketComment)
{
    if (ModelState.IsValid)
    {
        ...
        return RedirectToAction("Details", "Ticket", new { Id = ticket.ID });
    }
    return View(ticketComment);
}

A more MVC-centric example: https://www.stevefenton.co.uk/2011/04/asp-net-mvc-post-redirect-get-pattern/

Jasen
  • 14,030
  • 3
  • 51
  • 68
  • RedirectToAction....sounds like how I think it should work. Unfortunately I get an exception: {"Child actions are not allowed to perform redirect actions."} – Rachelle Janssen Nov 08 '16 at 21:09
  • The `Html.RenderAction("create", "TicketComments");` should be a form and triggered by the user to do a form POST. The way you have it now will trigger (as a child action) Create as soon as the view renders. – Jasen Nov 08 '16 at 21:19