2

I started working with MVC and i am currently working on an application. I ran into a small problem when I'm trying to pass some data from a view to a controller action.

This is my model :

public class TicketIndexModel
{
    public IEnumerable<Ticket> ticketList { get; set; }
    public Ticket newTicket { get; set; }

}

This is my controller action :

public ActionResult AddTicket(Ticket ticket)
    {
        string user = User.Identity.Name;
        TicketDetail ticketDetails = new TicketDetail();

        if (ModelState.IsValid)
        {
            ticket.DateCreated = DateTime.Now;
            ticket.Status = "submitted";
            ticket.UserName = user;
            db.Tickets.Add(ticket);
            db.SaveChanges();

         //some other stuff



            return RedirectToAction("Index");
        }

And in the view, first i show all the tickets and after that I have a small form to add a new ticket. This is how the form looks like.

@using (Html.BeginForm("AddTicket","Ticket",FormMethod.Post)) {

    <div class="editor-label">
        @Html.LabelFor(model => model.newTicket.Title)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.newTicket.Title)
        @Html.ValidationMessageFor(model => model.newTicket.Title)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.newTicket.Description)
    </div>
    <div class="editor-field">
        @Html.TextAreaFor(model => model.newTicket.Description, new { rows= "8",cols="2"})
        @Html.ValidationMessageFor(model => model.newTicket.Description)
    </div>

      <p>
        <input type="submit" value="Submit" />
    </p>

}

The problem I am facing is when I try to add a new ticket, the ticket parameter is always null, so If(ModelState.Isvalid) <- is always false and so i can not add new tickets to the DB.

Does anyone have any ideas why ?

Later Edit :

My model is now :

public IPagedList<Ticket> ticketList { get; set; }

    //[Required(ErrorMessage ="Title required")]
    [Display(Name = "Title")]
    public string TicketTitle { get; set; }

    //[Required(ErrorMessage="Description Required")]
    [Display(Name = "Description")]
    public string TicketDescription { get; set; }

My method is now :

    [HttpPost]
    public ActionResult AddTicket(TicketIndexModel newTicket)
    {
        string user = User.Identity.Name;     

        Ticket ticket = new Ticket();

        if (ModelState.IsValid)
        {
            ticket.Title = newTicket.TicketTitle;
            ticket.Description = newTicket.TicketDescription;
            ticket.DateCreated = DateTime.Now;
            ticket.Status = "open";
            ticket.UserName = user;
            db.Tickets.Add(ticket);
            db.SaveChanges();

The problem i now have is the following :

If in the model, i comment [Required] i can add a ticket, if not, in the controller, the newTicket in the signature is null every time i submit a new ticket. But, the controller enters the if(ModelState.IsValid) and i get an error at db.SaveChanges(ticket).

I need both server and client side validation. Can you help me ?

Mihai Tibrea
  • 641
  • 5
  • 23
  • 2
    Shouldn't your `AddTicket` Action have a `TicketIndexModel` parameter instead of `Ticket`? – Mohammad Sepahvand Apr 16 '13 at 19:50
  • Why use a TicketIndexModel when i only use a ticket ? – Mihai Tibrea Apr 16 '13 at 20:04
  • Investigate the values of your http POST request in the browser, like in the web developer bar of chrome. Then compare the values you send with the properties of your Ticket class. How do they look? – citykid Apr 16 '13 at 20:05
  • Check this for your latest error: http://stackoverflow.com/questions/5400530/validation-failed-for-one-or-more-entities-while-saving-changes-to-sql-server-da – Crwydryn Apr 16 '13 at 20:33

1 Answers1

2

Your AddTicket method should look like this

[HttpPost]
public ActionResult AddTicket(TicketIndexModel ticketIndexModel)

Then access newTicket from the object passed into it.

Crwydryn
  • 840
  • 6
  • 13
  • Not sure that solves it. First, HttpPost is an optional filter - here the request arrives in the post method, so this attribute would not change the problem asked for. Second, the question is about adding a Ticket, TicketIndexModel holds the Ticket collection beside the newTicket, which is not obvious to me either. So I assume the signature of the controller is ok. – citykid Apr 16 '13 at 20:03
  • @citykid it's only logical to expect the `AddTicket` Action's argument to be a `TicketIndexModel` since in his view he's accessing `model.newTicket` and `newTicket` is defined on `TicketIndexModel`. – Mohammad Sepahvand Apr 16 '13 at 20:07
  • While the new ticket surprises me too in the index model, it makes no sense at all to pass a ticket collection to the controller to create a new item. – citykid Apr 16 '13 at 20:10
  • I have used a break point, and the new parameter has the introduces values i give it, but at this line db.Tickets.Add(newTicket); newTicket has the title and description null again. – Mihai Tibrea Apr 16 '13 at 20:20
  • Like Mohammad suggested, I assumed from the view code that the view's model is TicketIndexModel. I agree that perhaps the TicketIndexModel isn't suited for this purpose though, and rather than having a Model with a collection and an individual object, its better to separate them, and have one view who's model is an IEnumerable, the purpose of which is just to list the Tickets, and then a separate view with a model of Ticket, that allows the user to add a new Ticket. – Crwydryn Apr 16 '13 at 20:20
  • But i need to have all the tickets and the form to add a ticket in the same view. – Mihai Tibrea Apr 16 '13 at 20:22
  • By the way. You should add the HttpPost attribute where appropriate to make the code more readable :) – Crwydryn Apr 16 '13 at 20:44