How to save data dynamically from a View in MVC5

asp.net asp.net-mvc-3 asp.net-mvc-4 c# entity-framework-6

Question

I want to build a Questionnaire MVC5 project. I have a MSSQL database with several tables like: Employee, Questions, Results ...

I made a new MVC5 project, I add it the model base on my database and I manage all CRUD operations need it.

Now I made an view for Questionar :

@model IEnumerable<ChestionarMVC.Models.FormQuestion>

@{
    ViewBag.Title = "Chestionar";
}

<h2>Chestionar</h2>

    @foreach (var item in Model)
    {
   @Html.Partial("_Chestionar",item)
    }
<input id="Submit1" type="submit" value="submit" />

And a partialView to show each question with 2 text area, one for the answer and one for some aditional info :

@model ChestionarMVC.Models.FormQuestion

<table border="1" style="width:100%">

        <tr>
            <td>
                @Html.DisplayFor(modelItem => Model.Question)
            </td>

        </tr>
        <tr>
            <td>
                Raspuns <br />
                <textarea id="TextArea1" rows="2" cols="80" style="width:800px; height:100px;"></textarea>
            </td>
        </tr>
        <tr>
            <td>
                Document <br />
                <textarea id="TextArea2" rows="2" cols="80" style="width:400px"></textarea>
            </td>
        </tr>
</table>

Now I want to save in the tblResults the QuestionID, Answer and Document. In webforms I made a usercontrol, then I used Foreach usercontrol , and saved to database.

In MVC how can I save all?

This is the QuestionsModel:

namespace ChestionarMVC.Models
{
    using System;
    using System.Collections.Generic;

    public partial class FormQuestion
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public FormQuestion()
        {
            this.FormResults = new HashSet<FormResult>();
            this.TBLPos = new HashSet<TBLPos>();
        }

        public int idQuestion { get; set; }
        public string Question { get; set; }
        public int idCategory { get; set; }
        public int idPosition { get; set; }
        public Nullable<int> Ordine { get; set; }

        public virtual FormCategory FormCategory { get; set; }
        public virtual Formular Formular { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<FormResult> FormResults { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<TBLPos> TBLPos { get; set; }
    }
}

this is the ResultsMOdel:

namespace ChestionarMVC.Models
{
    using System;
    using System.Collections.Generic;

    public partial class FormResult
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public FormResult()
        {
            this.Documentes = new HashSet<Documente>();
        }

        public int idResult { get; set; }
        public int idUser { get; set; }
        public int idQuestion { get; set; }
        public string Answer { get; set; }
        public string RefferenceDocument { get; set; }
        public Nullable<System.DateTime> StampDate { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Documente> Documentes { get; set; }
        public virtual Employee Employee { get; set; }
        public virtual FormQuestion FormQuestion { get; set; }
    }
}

this is the Questionnaire ActionResult used to generate the Questionnaire-View:

    public ActionResult Chestionar()
    {
        var formQuestions = db.FormQuestions;
        return View(formQuestions.ToList());
    } 
1
0
8/23/2015 12:46:26 PM

Accepted Answer

Start by creating a view model containing the properties you want for the view (note add other validation attributes as required to suit your needs)

public class QuestionVM
{
  public int ID { get; set; }
  public string Question { get; set; }
  [Required(ErrorMessage = "Please enter and answer")]
  public string Answer { get; set; }
  public string Document { get; set; }
}

Then create an EditorTemplate. In /Views/Shared/EditorTemplates/QuestionVM.cshtml

@model QuestionVM
@Html.HiddenFor(m => m.ID)
@Html.HiddenFor(m => m.Question)
@Html.DisplayNameFor(m => m.Question)
@Html.DisplayFor(m => m.Question)
@Html.LabelFor(m => m.Answer)
@Html.TextAreaFor(m => m.Answer)
@Html.ValidationMessageFor(m => m.Answer)
... // ditto for Document (as for Answer)

And in the main view

@model IEnumerable<QuestionVM>
@using (Html.BeginForm())
{ 
  @Html.EditorFor(m => m)
  <input type="submit" ... />
}

Note that the EditorFor() method will generate the html for each Question based on the template, and importantly will add the correct name attributes that enable your form controls to be posted back and bound to your model

The in the controller

public ActionResult Chestionar()
{
  // Get data model and map to view models
  var model = db.FormQuestions.Select(q => new QuestionVM()
  {
    ID = q.idQuestion,
    Question = q.Question,
    Answer = .....,
    Document = .... // see notes below
  };
  return View(model);
}
[HttpPost]
public ActionResult Chestionar(IEnumerable<QuestionVM> model)
{
  if (!ModelState.IsValid)
  {
    return View(model);
  }
  // Get the data model again, map the view model properties back to the data model
  // update properties such as user and date
  // save and redirect
}

Side note: your question indicates an (one) Answer and Document for each question, yet you current models for the Question have a collection (ICollection<FormResult> FormResults) containing properties for the Answer and RefferenceDocument so its not clear if you want to add multiple answers and documents for each Question, or just one.

1
8/23/2015 1:14:21 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow