Model binder returns nullreference - asp.net-mvc

#for (var i = 0; i < Model.Roles.Count; i++)
{
<div class="row" style="margin-bottom: .5rem;">
<div class="col-lg-3"></div>
<div class="col-lg-3">
<li class="list-group-item" style="background: #f5f6f7; border: none;">
#Html.Hidden("Roles[" + i + "].id", Model.Roles[i].id)
<label for="Roles_#(i)_ischecked" class="label">
#Html.CheckBox("Roles[" + i + "].ischecked", Model.Roles[i].ischecked)
#Model.Roles[i].name
</label>
</li>
</div>
</div>
}
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object
but the real object is referenced through these codes
return View(new UsersNew
{
Roles = Database.Session.Query<Role>().Select(role => new RoleCheckbox
{
id = role.id,
ischecked = false,
name = role.name
}).ToList()
})
I even referenced to my View as follow s
#model EtlGui.ViewModels.UsersNew
my ViewModel looks like this
public class UsersNew
{
public IList<RoleCheckbox> Roles { get; set; }
[Required,MaxLength(128)]
public string username { get; set; }
[Required,DataType(DataType.Password)]
public string password { get; set; }
[Required,MaxLength(256),DataType(DataType.EmailAddress)]
public string email { get; set; }
}
what am i doing wrong here?

Related

Binding in Razor returns null (OnPostAsync)

In the code below, we all values in QuestionViewModel are null. Any ideas what I am doing wrong about binding?
cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using VerityLearn.DataAccess;
using VerityLearn.Domain;
using VerityLearn.DataAccess.UOW;
using VerityLearn.WebUI.ViewModels;
namespace VerityLearn.WebUI.Pages.Questions
{
[Authorize]
public class StudentQuestionsModel : PageModel
{
private readonly SignInManager<VerityUser> _signInManager;
private readonly UserManager<VerityUser> _userManager;
private readonly IStudentQuesionsUOW _studentQuesionsUOW;
private readonly VerityLearn.DataAccess.VerityContext _context;
public StudentQuestionsModel(
VerityContext context,
SignInManager<VerityUser> signInManager,
UserManager<VerityUser> userMrg,
IStudentQuesionsUOW studentQuesionsUOW
)
{
_context = context;
_signInManager = signInManager;
_userManager = userMrg;
_studentQuesionsUOW = studentQuesionsUOW;
} // end public StudentQuestionsModel(VerityContext context, SignInManager<VerityUser> signInManager, UserManager<VerityUser> userMrg)
#region User Properties
public VerityUser VerityUser { get; set; }
//[TempData]
//public string UserId { get; set; }
public Student Student { get; set; }
public Prospect Prospect { get; set; }
public Parent Parent { get; set; }
public ExamUserViewModel ExamUserViewModel { get; set; }
#endregion // User Properties
public DateTime DateStarted { get; set; }
public Exam Exam { get; set; }
[TempData]
public int ExamId { get; set; }
ExamQuestion ExamQuestion { get; set; }
public List<ExamQuestion> ExamQuestions { get; set; }
[TempData]
public int NbrOfExamQuestions { get; set; }
public ExamViewModel ExamViewModel { get; set; }
[TempData]
public int QuestionNdx { get; set; }
[BindProperty]
public QuestionViewModel QuestionViewModel { get; set; }
[ViewData]
public string Message { get; set; }
[BindProperty]
public Question Question { get; set; }
public async Task OnGetAsync(int? examId, int? questionNdx)
{
Message = string.Empty;
if (_signInManager.IsSignedIn(HttpContext.User))
{
string email = HttpContext.User.Identity.Name;
VerityUser = await _studentQuesionsUOW.GetVerityUser(email);
//UserId = VerityUser.Id.ToString();
// TODO: Setup priorities of setting Student, Prospect and Parent properties, might involve Enrollments 4/30/2020
//Student = await _context.Students.Where(s => s.UserId == VerityUser.Id).FirstOrDefaultAsync<Student>();
//Prospect = await _context.Prospects.Where(p => p.UserId == VerityUser.Id).FirstOrDefaultAsync<Prospect>();
//Parent = await _context.Parents.Where(p => p.UserId == VerityUser.Id).FirstOrDefaultAsync<Parent>();
DateStarted = DateTime.Now;
if ((examId != null) && (examId.Value > 0))
{
ExamId = examId.Value;
Exam = await _context.Exams.Where(e => e.ExamId == examId)
.Include(e => e.Course).ThenInclude(c => c.Subject).FirstOrDefaultAsync<Exam>();
if (Exam != null)
{
ExamUserViewModel = new ExamUserViewModel
{
ExamUserId = 0,
ExamId = Exam.ExamId,
TimeStarted = DateTime.Now,
Status = ExamUserStatus.InProgress,
StudentId = VerityUser.StudentId,
ProspectId = VerityUser.ProspectId,
ParentId = VerityUser.ParentId
};
// TODO: If this is a new ExamUser, we must insert it to VerityLearnDB2.ExamUsers
if (NbrOfExamQuestions == 0)
{
ExamQuestions = await _context.ExamQuestions
.Where(eq => eq.ExamId == examId)
.ToListAsync<ExamQuestion>();
NbrOfExamQuestions = ExamQuestions.Count;
TempData.Keep("NbrOfExamQuestions");
} // endif (NbrOfExamQuestions == 0)
if ((questionNdx == null) || (questionNdx.Value == 0))
{
questionNdx = 1;
} // endif ((questionNdx == null) || (questionNdx.Value == 0))
QuestionNdx = questionNdx.Value;
TempData.Keep("QuestionNdx");
ExamQuestion = await _context.ExamQuestions
.Include(eq => eq.Question)
.ThenInclude(q => q.Options)
.Where(eq => eq.ExamQuestionOrder == questionNdx)
.FirstOrDefaultAsync<ExamQuestion>();
QuestionViewModel = new QuestionViewModel
{
QuestionId = ExamQuestion.QuestionId,
ExamQuestionOrder = ExamQuestion.ExamQuestionOrder,
QuestionText = ExamQuestion.Question.QuestionText,
IsSingleSelection = ExamQuestion.Question.IsSingleSelection,
Options = new List<OptionViewModel>()
};
ExamViewModel = new ExamViewModel
{
ExamId = Exam.ExamId,
ExamName = Exam.ExamName,
Questions = new List<QuestionViewModel>()
};
ExamViewModel.Questions.Add(QuestionViewModel);
ExamViewModel.ExamUserViewModel = ExamUserViewModel;
List<AnswerOption> answerOptions = _context.AnswerOptions
.Where(ao => ao.QuestionId == ExamQuestion.QuestionId)
.ToList<AnswerOption>();
foreach (AnswerOption ao in answerOptions)
{
OptionViewModel ovm = new OptionViewModel
{
OptionId = ao.OptionId,
OptionText = ao.OptionText,
IsCorrect = ao.IsCorrect
};
ovm.UserExamOptionViewModel = new UserExamOptionViewModel
{
UserExamOptionId = ExamUserViewModel.ExamUserId,
UserExamId = 0,
OptionId = ao.OptionId,
IsSelected = false
};
QuestionViewModel.Options.Add(ovm);
}
}
else
{
Message = String.Format("Error: Exam with Identifier, {0}, was not found.", examId);
}
}
else
{
Message = String.Format("Error: Exam with Identifier, {0}, was not found.", examId);
}
}
else
{
Message = "Error: Login is required.";
}
}
public async Task<IActionResult> OnPostAsync(QuestionViewModel QuestionViewModel)
{
var t = QuestionViewModel;
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Question).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
}
return RedirectToPage("./Index");
}
}
}
cshtml file:
#page "{examId:int?}"
#model VerityLearn.WebUI.Pages.Questions.StudentQuestionsModel
#{
ViewData["Title"] = "StudentQuestions";
}
#if (String.IsNullOrEmpty(#Model.Message))
{
<div class="row" style="background-color: #5D2685; color: #FFFF80;">
<div class="col-md-6">
<h4>Exam: #Html.DisplayFor(model => model.Exam.ExamName)</h4>
</div>
<div class="col-md-6">
<h4>Course: #Html.DisplayFor(model => model.Exam.Course.CourseName)</h4>
</div>
</div>
<br />
<br />
<div>
<h4>Question</h4>
<hr />
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Question.QuestionId" />
<div class="form-group">
<label asp-for="Question.QuestionText" class="control-label"></label>
<input asp-for="Question.QuestionText" class="form-control" />
<span asp-validation-for="Question.QuestionText" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Question.KeyToAnswer" class="control-label"></label>
<input asp-for="Question.KeyToAnswer" class="form-control" />
<span asp-validation-for="Question.KeyToAnswer" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Question.IsSingleSelection" class="control-label"></label>
<input asp-for="Question.IsSingleSelection" class="form-control" />
<span asp-validation-for="Question.IsSingleSelection" class="text-danger"></span>
</div>
<label asp-for="QuestionViewModel.QuestionText" class="control-label"></label>
#if (Model.QuestionViewModel.IsSingleSelection.Value)
{
<p>Select the correct option.</p>
#foreach (OptionViewModel opt in Model.QuestionViewModel.Options)
{
<input type="radio" name="option" value="#opt.UserExamOptionViewModel.IsSelected"><label for=" #opt.OptionText"> #opt.OptionText </label><br />
}
}
else
{
<p>Select the correct options (More than one).</p>
#foreach (OptionViewModel opt in Model.QuestionViewModel.Options)
{
<input type="checkbox" name="option" value="#opt.UserExamOptionViewModel.IsSelected"><label for=" #opt.OptionText"> #opt.OptionText </label><br />
}
}
#{
var prevDisabled = (Model.QuestionNdx <= 1) ? "disabled" : "";
var nextDisabled = (Model.QuestionNdx >= Model.NbrOfExamQuestions) ? "disabled" : "";
}
<button type="submit" asp-route-questionIndex="#(Model.QuestionNdx - 1)" class="btn btn-primary #prevDisabled">Previous</button>
<button type="submit" asp-route-questionIndex="#(Model.QuestionNdx + 1)" class="btn btn-primary #nextDisabled">Next</button>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
}
else
{
<div class="row" style="background-color: #5D2685; color: #FFFF80;">
<div class="col-md-6">
<h4>#Model.Message</h4>
</div>
</div>
}
UPDATE (5/11/2020):
I have simplified the view like this:
#foreach(OptionViewModel opt in Model.QuestionViewModel.Options)
{
optionIndex++;
#Html.RadioButtonFor(model => model.QuestionViewModel.Options[optionIndex].OptionText, #opt.OptionText);
#opt.OptionText<br />
}
I see 4 options but all of them are selected. I would expect only one radio button to be selected at a time. I click Next anyway
I now see the option texts are bound. Question: How to figure out which one is selected?
The problem is you are using a complex model, but your HTML does not indicate that the model is complex. I have created a demo to highlight the issue:
Here Student contains Address and List<Subject> (it is complex model)
public class Subject
{
public string SubjectName { get; set; }
}
public class Address
{
public string StreetAddress { get; set; }
}
public class Student
{
public string Name { get; set; }
public Address HomeAddress { get; set; }
public List<Subject> Subjects { get; set; }
}
When displaying a complex model in a form, you need to use the entire model in the html input tag, this way ASP.NET MVC ModelBinder knows how to bind your HTML inputs to your server-side model.
The above demo has 3 inputs, I am using HTML.TextBoxFor which is the older equivalent of asp-for Tag Helper.
Input 1:
#Html.TextBoxFor(model => model.Name)
Generates the following HTML:
<input id="Name" name="Name" type="text" value="John Smith">
Model binder uses name and binds the above input to Student.Name
Input 2
#Html.TextBoxFor(model => model.HomeAddress.StreetAddress)
Generates the following HTML:
<input id="HomeAddress_StreetAddress" name="HomeAddress.StreetAddress" type="text" value="some address">
Here Model binder knows that this input should be bound to Student.HomeAddress.StreetAddress because that's what the input name indicates
Input 3
#Html.TextBoxFor(model => model.Subjects[0].SubjectName)
Generates the following HTML:
<input id="Subjects_0__SubjectName" name="Subjects[0].SubjectName" type="text" value="Math">
Model binder will bind the above input to Student.Subjects[0].SubjectName
See this article for more info.
In your example, Model Binder has no way to know that option belongs to QuestionViewModel.Options because you are not indicating it in the input name:
<input type="checkbox" name="option" value="#opt.UserExamOptionViewModel.IsSelected">
Make sure you're using [BindProperty] attribute.

How can i take many textboxes' value on Post in MVC

i have a problem about MVC, but first I am sorry for my english :D .
Now i am trying to make a form for users and i have a critical issue when i want connect to values with database.
My Form is like this : https://i.hizliresim.com/vJ6r2p.png
Models :
[Table("Testers")]
public class Testers
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[StringLength(50),Required]
public string testerName { get; set; }
public ICollection<Scores> Scores { get; set; }
}
[Table("Technologies")]
public class Technologies
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[StringLength(50)]
public string technologyName { get; set; }
[StringLength(50)]
public string type { get; set; }
}
[Table("Scores")]
public class Scores
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[DefaultValue(0)]
public int score { get; set; }
public virtual Testers tester { get; set; }
public virtual Technologies technology { get; set; }
}
ViewModels:
public class TechnologiesView
{
public List<Technologies> Technologies { get; set; }
public Scores Scores { get; set; }
}
Controller :
public ActionResult Page2()
{
TechnologiesView allTechs = new TechnologiesView();
allTechs.Technologies = db.Technologies.ToList();
return View(allTechs);
}
View:
#model TechnologiesView
#{
ViewBag.Title = "Page2";
}
<style>
#lang {
font-size: 15px;
color: gray;
}
#tech {
font-size: 13px;
color: gray;
}
</style>
<div class="container">
<div class="row col-xs-12 bilgi" style="color:black">
#HelperMethods.Title("Kendini Skorla!")
<br />
<i>Bilgi Düzeyini 0 ile 5 puan arasında notlar mısın? (0=Hiç 5= İleri Seviye)</i>
</div>
</div>
<hr />
#using (Html.BeginForm())
{
<div class="container-fluid" style="padding-left:50px; margin:0px">
<div class="row" id="lang">
#foreach (Technologies techs in Model.Technologies)
{
if (techs.type == "lang")
{
<div class="col-md-1 col-sm-2 col-xs-6">
#(techs.technologyName)
</div>
<div class="col-md-1 col-sm-2 col-xs-6">
(#(Html.TextBoxFor(x => x.Scores.score, new
{
id = techs.ID,
name = "techID",
style = "display:inline; width:20px; height:20px; font-size:smaller; padding:0px; text-align:center",
#class = "form-control"
})))
</div>
}
}
</div>
<hr style="color:black" />
<div class="row" id="tech">
#foreach (Technologies techs in Model.Technologies)
{
if (techs.type == "tech")
{
<div class="col-md-1 col-sm-2 col-xs-6" id="tech">
#(techs.technologyName)
</div>
<div class="col-md-1 col-sm-2 col-xs-6">
#Html.HiddenFor(x=>techs.ID)
(#(Html.TextBoxFor(x => x.Scores.score, new
{
id = techs.ID,
name = "techID",
style = "display:inline; width:20px; height:20px; font-size:smaller; padding:0px; text-align:center",
#class = "form-control"
})))
</div>
}
}
</div>
<hr />
<div class="row col-xs-12" id="lang">
<span>Kullandığınız IDE’ler (yazınız)</span>
<br />
<div style="margin-bottom:10px; text-align:center">
#HelperMethods.TextArea("Ide", 3)
</div>
</div>
<div style="text-align:right; margin-bottom:10px">
#HelperMethods.Button("btnPage2")
</div>
</div>
}
Now user has to give a score to him/herself for every technologies or languages and after this i want to when user click to button "Follow the next page(it's turkish)" i will select the last saved user from maxID value in Testers and i have to connect scores with technologies and testers but i don't know how can i get textboxes' values and which technology's value is this value on post :D
You generating form controls which have no relationship at all to your model (which is also wrong anyway). Never attempt to change the name attribute when using the HtmlHelper methods (and there is no reason to change the id attribute either)
Next, you cannot use a foreach loop to generate form controls for a collection. You need a for loop or EditorTemplate to generate the correct name attributes with indexers. Refer this answer for a detailed explanation.
Then you cannot use a if block inside the loop (unless you include a hidden input for the collection indexer), because by default the DefaultModelBinder required collection indexers to start at zero and be consecutive.
First start by creating view models to represent what your want to display/edit in the view.
public class ScoreVM
{
public int ID { get; set; }
public string Name { get; set; }
public int Score { get; set; }
}
public class TechnologiesVM
{
public List<ScoreVM> Languages { get; set; }
public List<ScoreVM> Technologies { get; set; }
public string Notes { get; set; } // for your textarea control
}
Note you will probably want to add validation attributes such as a [Range] attribute for the Score property
In the GET method, initialize and populate your view model and pass it to the view
public ActionResult Page2()
{
IEnumerable<Technologies> technologies = db.Technologies;
TechnologiesVM model = new TechnologiesVM
{
Languages = technologies.Where(x => x.type == "lang")
.Select(x => new ScoreVM{ ID = x.ID, Name = x.technologyName }).ToList(),
Technologies = technologies.Where(x => x.type == "tech")
.Select(x => new ScoreVM{ ID = x.ID, Name = x.technologyName }).ToList(),
};
return View(model);
}
and in the view
#model TechnologiesVM
....
#using (Html.BeginForm())
{
....
#for (int i = 0; i < Model.Languages.Count; i++)
{
#Html.HiddenFor(m => m.Languages[i].ID)
#Html.HiddenFor(m => m.Languages[i].Name)
#Html.LabelFor(m => m.Languages[i].Score, Model.Languages[i].Name)
#Html.TextBoxFor(m => m.Languages[i].Score)
#Html.ValidationMessageFor(m => m.Languages[i].Score)
}
#for (int i = 0; i < Model.Languages.Count; i++)
{
.... // repeat above
}
#Html.LabelFor(m => m.Notes)
#Html.TextAreaFor(m => m.Notes)
#Html.ValidationMessageFor(m => m.Notes)
<input type="submit" />
}
and the POST method will be
public ActionResult Page2(TechnologiesVM model)
{
if (!ModelState.IsValid)
{
return View(model);
}
... // save the data and redirect
}

How do I get my view to show my database table

i'm new to ASP.net. I am trying to figure out how to get my Edit/Display pages working properly for a multiselect listbox.
My create works fine, and saves to my database, but I cannot figure out how to return to the edit page, and still see the values selected.
Hopes this makes sense.
Here is the code that I have for the create method. The record saves fine in both tables, but I am having trouble getting the values from my Options table.
I want to try to make the Edit view look like the Create View
Controller
[HttpPost]
public IActionResult Create(MusicViewModel model)
{
if(ModelState.IsValid)
{
var album = new Music();
album.Album = model.Album;
album.Artist = model.Artist;
album.Label = model.Label;
album.Review = model.Review;
album.ReleaseDate = model.ReleaseDate;
foreach(Types type in model.Options)
{var opt = new Options();
opt.Music = album;
opt.Types = type;
_musicData.AddOptions(opt);
}
_musicData.Add(album);
_musicData.Commit();
return RedirectToAction("Details", new { id = album.MusicID });
}
return View();
}
Music.cs
public enum Types
{
Spotify,
Groove,
CD,
Vinyl,
Pandora
}
public class Music
{
public int MusicID { get; set; }
[Required]
[MaxLength(50),MinLength(5)]
public string Artist { get; set; }
[Required, MinLength(5)]
public string Album { get; set; }
public int Rating { get; set; }
public Label Label { get; set; }
[DataType(DataType.Date)]
[Display(Name ="Release Date")]
public DateTime ReleaseDate { get; set; }
public string Review { get; set; }
public List<Options> Options { get; set; }
}
public class Options
{
public int OptionsID { get; set; }
public Types Types { get; set; }
public int MusicID { get; set; }
public Music Music { get; set; }
}
public class MusicDbContext:DbContext
{
public DbSet<Music> Albums { get; set; }
public DbSet<Options> Options { get; set; }
}
View
#model Music
....
<form asp-action="Create" method="post">
<div class="row">
<div class="col-md-3 col-md-offset-2">
<fieldset class="form-group">
<label asp-for="Artist"></label>
<input class="form-control" asp-for="Artist" />
<span asp-validation-for="Artist" class="alert"></span>
</fieldset>
</div>
<div class="col-md-3">
<fieldset class="form-group">
<label asp-for="Album"></label>
<input class="form-control" asp-for="Album" />
<span asp-validation-for="Album" class="alert"></span>
</fieldset>
</div>
<div class="col-md-3">
<label asp-for="Label"></label>
#Html.DropDownList("Label", Html.GetEnumSelectList(typeof(Label)), "-------", new { #class = "form-control" })
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-2">
<fieldset class="form-group">
<label asp-for="Options"></label>
<select multiple class="form-control" asp-for="Options"
asp-items="#Html.GetEnumSelectList(typeof(Types))"></select>
</fieldset>
</div>
<div class="col-md-3">
<fieldset class="form-group">
<label asp-for="ReleaseDate"></label>
<input type="text" asp-for="ReleaseDate" class="DateBox form-control" />
<span asp-validation-for="ReleaseDate" class="alert"></span>
</fieldset>
</div>
</div>
<div class="col-md-offset-3"><input class="btn btn-info" type="submit" value="Submit" /></div>
</form>
I figured it out, probably not the most efficient way, but at least the code works
[HttpPost]
public IActionResult Edit(int id,MusicViewModel model)
{
var album = _musicData.GetM(id);
if (album != null && ModelState.IsValid)
{
album.Album = model.Album;
album.Artist = model.Artist;
album.Label = model.Label;
album.Review = model.Review;
album.ReleaseDate = model.ReleaseDate;
_musicData.RemoveOptions(id);
foreach (Types type in model.Options)
{
var opt = new Options();
opt.MusicID = id;
opt.Types = type;
_musicData.AddOptions(opt);
}
_musicData.Commit();
return RedirectToAction("Details",id);
}
return View(album);
}

if value null in radio button list does not show radio button mvc4

I have in model having the questions and answer list. In some of the questions having 4 options and some of the questions having the 2 options.
I am getting the options from the back end and i'm binding from model class into the razor view.
Now if the answer value null means radio button is showing but i don't want to radio button if the radio button option value nulls.
#for (int j = 0; j < Model.Count; j++)
{
i++;
<div class="panel-heading online-test" role="tab" id="">
<h5 class="panel-title">
#Html.HiddenFor(m => m[j].ID)
#Html.HiddenFor(m => m[j].SkillId)
#i) #Html.DisplayFor(m => m[j].QuestionText)
</h5>
</div>
foreach (var k in Model[j].Options)
{
<div class="panel-collapse">
<div class="panel-body online-test-options">
<div class="input-group">
<div class="col-lg-12" id="radiolist">
#Html.RadioButtonFor(m => m[j].SelectedAnswer, "A")
<label for="#k.AnswerId">#k.Option1</label>
</div>
<div class="col-lg-12">
#Html.RadioButtonFor(m => m[j].SelectedAnswer, "B")
<label for="#k.AnswerId">#k.Option2</label>
</div>
<div class="col-lg-12">
#Html.RadioButtonFor(m => m[j].SelectedAnswer, "C")
<label for="#k.AnswerId">#k.Option3</label>
</div>
<div class="col-lg-12">
#Html.RadioButtonFor(m => m[j].SelectedAnswer, "D")
<label for="#k.AnswerId">#k.Option4</label>
</div>
</div>
</div>
</div>
}
}
public class QuestionsModel
{
public decimal ID { set; get; }
public decimal SkillId { get; set; }
public string QuestionText { set; get; }
public List<Answer> Options { set; get; }
public string SelectedAnswer { set; get; }
public QuestionsModel()
{
Options = new List<Answer>();
}
}
public class Answer
{
public int AnswerId { get; set; }
public string Option1 { set; get; }
public string Option2 { set; get; }
public string Option3 { set; get; }
public string Option4 { set; get; }
}
public class Evaluation
{
public List<QuestionsModel> Questions { set; get; }
public Evaluation()
{
Questions = new List<QuestionsModel>();
}
}
Please help to solve..
Thanks in Advance.

Creating an MVC form using partial views each with complex models not binding to main model

I'm working on a form that has a main model being passed to the view. The model has sub-models within it, with partial views to render that content. The problem is that when I fill out the form, only those parameters on the main form get bound back to the model when the form is submitted.
I tried changing the Html.RenderPartial to a Html.EditorFor, and while it fixed my model binding problem, it removed all of my html formatting from the partial view.
Is there a way I can either bind my partial view elements to the main form model, or keep the html structure of my partial view using EditorFor?
Below is my code (I chopped out a bunch of stuff - especially from my main view - to try to simplify what I'm looking for).
This is my model:
public class ShipJobs
{
public String Job { get; set; }
public String Quote { get; set; }
public String PartName { get; set; }
public String Rev { get; set; }
public String Customer { get; set; }
public String CustomerName { get; set; }
public String TrackingNumber { get; set; }
public Int32 ShippedQuantity { get; set; }
public Boolean Certs { get; set; }
public Double ShippingCharges { get; set; }
public DateTime ShipDate { get; set; }
public String SelectedFreightTerms { get; set; }
public IEnumerable<SelectListItem> FreightTerms { get; set; }
public String SelectedContact { get; set; }
public IEnumerable<SelectListItem> Contacts { get; set; }
public String SelectedShipVia { get; set; }
public IEnumerable<SelectListItem> ShipVia { get; set; }
public Models.GreenFolders.Address Address { get; set; }
}
public class Address
{
public AddressType Type { get; set; }
public String ShipToId { get; set; }
public String ContactName { get; set; }
public String AddressName { get; set; }
public String Line1 { get; set; }
public String Line2 { get; set; }
public String City { get; set; }
public String State { get; set; }
public String Zip { get; set; }
public String Phone { get; set; }
public SelectList ShipToAttnDropDown { get; set; }
public IEnumerable<SelectListItem> ShipToDropDown { get; set; }
}
Controller:
public ActionResult ShipJobs(String Job, Models.Shipping.ShippingModel.ShipJobs Packlist, Models.GreenFolders.Address ShipAddress, String Submit = "")
{
var Model = new Models.Shipping.ShippingModel.ShipJobs();
if (Submit == "loadjob")
{
var shippingHelper = new BLL.Shipping.ShippingMethods(_company);
Model = shippingHelper.GetShipJobModel(Job);
Model.Address = shippingHelper.GetShipAddress(Job);
}
else if (Submit == "createpacklist")
{
}
ViewBag.Company = _company.ToString();
return View(Model);
}
Main View:
#model Models.Shipping.ShippingModel.ShipJobs
#{
ViewBag.Title = "ShipJobs";
String Company = ViewBag.Company.ToString();
}
#using (Html.BeginForm("ShipJobs", "Shipping", FormMethod.Post, new { Class = "form-horizontal" }))
{
<div class="row">
<div class="col-md-6">
<!-- Basic Form Elements Block -->
<div class="block">
<!-- Basic Form Elements Title -->
<div class="block-title">
<h2>Load <strong>Job</strong></h2>
</div>
<!-- END Form Elements Title -->
<!-- Basic Form Elements Content -->
#using (Html.BeginForm("ShipJobs", "Shipping", FormMethod.Post, new { Class = "form-horizontal form-bordered" }))
{
<div class="form-group">
<label class="col-md-3 control-label" for="example-text-input">Job Number</label>
<div class="col-md-9">
#Html.TextBoxFor(model => model.Job, new { id = "example-text-input", Name = "Job", Class = "form-control" })
</div>
</div>
<div class="form-group form-actions">
<div class="col-md-9 col-md-offset-3">
<button type="submit" class="btn btn-sm btn-primary" name="submit" value="loadjob"><i class="fa fa-angle-right"></i> Load Job Info</button>
<button type="reset" class="btn btn-sm btn-warning"><i class="fa fa-repeat"></i> Reset</button>
</div>
</div>
}
</div>
</div>
<div class="col-md-6">
#if (Model.Address != null && Model.Address != null)
{
#Html.EditorFor(model => model.Address)
//Html.RenderPartial("../Shared/_Address", Model.ShipInfo);
}
</div>
#Html.HiddenFor(model => model.Quote)
#Html.HiddenFor(model => Company)
</div>
}
Partial view:
#model Models.GreenFolders.Address
<!-- Block -->
<div class="block">
<div class="block-title">
#if(Model.Type == Models.GreenFolders.AddressType.Shipping)
{
<h2 style="float: right; margin-top: -9px; margin-right: -10px;">
<div class="dropdown shiptoddl">
<button class="btn btn-default dropdown-toggle" type="button" id="shiptoddl" data-toggle="dropdown" aria-expanded="true">
#Model.ShipToDropDown.Where(x => x.Selected).FirstOrDefault().Text
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
#foreach (SelectListItem selectlistitem in Model.ShipToDropDown)
{
<li role="presentation"><a role="menuitem" tabindex="-1" href="#" data-value="#selectlistitem.Value" data-selected="#selectlistitem.Selected">#selectlistitem.Text</a></li>
}
</ul>
</div>
#*#Html.DropDownList("shiptoddl", (SelectList)Model.ShipToDropDown, new { #class = "shiptoddl", id = "shiptoddl" })*#
</h2>
}
<h4><strong>#Model.Type.ToString()</strong> Address</h4>
</div>
#{ Html.RenderPartial("../Shared/_AddressDetails", Model); }
</div>
<!-- END Block -->

Resources