Reputation: 1368
today i have a requirement where i have to submit a user's education details to the db. First of all i will explain from the entities, i have a one to many relation between the user and Education table, ie a user can can have multiple education details.
My EducationalBackground model looks like this
public class EducationalBackground
{
public int EducationalBackgroundID { get; set; }
public string UniversityOrCollege { get; set; }
public string AreaOfStudy { get; set; }
public string Degree { get; set; }
public string YearReceived { get; set; }
}
My Instructor Model which is my main model looks like this which contains a list of EducationBackground.
public class InstructorApplicationViewModel
{
public InstructorApplicationViewModel()
{
EducationalBackgrounds = new List<EducationalBackGround>
{
new EducationalBackGround {
AreaOfStudy = string.Empty,
Degree = string.Empty,
UniversityOrCollege = string.Empty,
YearReceived = string.Empty
}
};
}
public IList<EducationalBackGround> EducationalBackgrounds { get; set; }
public int CurrentUserId { get; set; }
[Required]
public string Experience { get; set; }
[Required]
public bool WillingToTravel { get; set; }
}
My view looks like this
@model PaulSchool.ViewModels.InstructorApplicationViewModel
@{
ViewBag.Title = "ApplyToBecomeInstructor";
}
<h2>
ApplyToBecomeInstructor</h2>
<script src="@Url.Content("~/Scripts/EducationalBackgroundListEditor.js")" type="text/javascript"> </script>
@using (Html.BeginForm())
{
<fieldset>
<legend>ApplyToBecomeInstructor</legend>
<div class="editor-label">
<p>
Information from your user profile will be considered when applying to become an
Instructor</p>
</div>
@Html.HiddenFor(model => model.CurrentUserId)
<div class="editor-label">
@Html.LabelFor(model => model.EducationalBackgrounds)
</div>
<div id="editorRows">
@Html.EditorFor(model => model.EducationalBackgrounds)
</div>
@Html.ActionLink("Add additional educational background.", "EducationalBackground", null, new { id = "addItem" })
<div class="editor-label">
@Html.LabelFor(model => model.Experience)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Experience)
</div>
<div class="editor-label">
Are you willing to travel?
</div>
<div class="editor-field">
@Html.EditorFor(model => model.WillingToTravel)
</div>
<p>
<input type="submit" value="Create" id="btnSubmit" />
</p>
<div class="newRow" style="display: none;">
<div class="editorRow">
<p>
<label>
UniversityOrCollege</label>
<input class="university" type="text" value="" />
</p>
<p>
<label>
AreaOfStudy</label>
<input class="area" type="text" value="" />
</p>
<p>
<label>
Degree</label>
<input class="degree" type="text" value="" />
</p>
<p>
<label>
YearReceived</label>
<input class="year" type="text" value="" />
</p>
<div>
<a href="javascript:void(0);" class="deleteRow">Delete</a>
</div>
</div>
</div>
</fieldset>
}
<div>
@Html.ActionLink("Back", "Index")
</div>
I have included a editor template in the Views/Shared/EditorTemplate folder to include the educationbackground details, which will act as a partial view as well as EditorTemplate
@model PaulSchool.ViewModels.EducationalBackGround
<div class="editorRow">
<p>
@Html.LabelFor(model => model.UniversityOrCollege)
@Html.TextBoxFor(model => model.UniversityOrCollege, new { @class="university" })
</p>
<p>
@Html.LabelFor(model => model.AreaOfStudy)
@Html.TextBoxFor(model => model.AreaOfStudy, new { @class="area" })
</p>
<p>
@Html.LabelFor(model => model.Degree)
@Html.TextBoxFor(model => model.Degree, new { @class = "degree" })
</p>
<p>
@Html.LabelFor(model => model.YearReceived)
@Html.TextBoxFor(model => model.YearReceived, new { @class = "year" })
</p>
<div>
<a href="javascript:void(0);" class="deleteRow">Delete</a>
</div>
</div>
I have a written a JQuery script like this tho post the values to the controller and was able to post everything to the model except the list of background details
<script type="text/javascript">
$('#btnSubmit').click(function () {
instructorUrl = '@Url.Action("ApplyToBecomeInstructor", "InstructorApplication")';
var user = [];
var educationList = [];
var currentUser = '@Model.CurrentUserId';
var experience = $('#Experience').val();
var isWilling = $('#WillingToTravel').is(":checked");
$('#editorRows .editorRow').each(function () {
var education = {
UniversityOrCollege: $(this).find('.university').val(),
AreaOfStudy: $(this).find('.area').val(),
Degree: $(this).find('.degree').val(),
YearReceived: $(this).find('.year').val()
}
educationList.push(education);
});
var applicationFromView = {
EducationalBackgrounds: educationList,
CurrentUserId: currentUser,
Experience: experience,
WillingToTravel: isWilling
}
$.ajax({
type: 'POST',
url: instructorUrl,
dataType: "json",
data: applicationFromView,
success: function (data) {
},
error: function (a, b, c) {
alert('A problem ocurred');
}
});
});
</script>
Also my controller looks like this
[HttpPost]
public ActionResult ApplyToBecomeInstructor(InstructorApplicationViewModel applicationFromView)
{
Student thisStudent = this.db.Students.FirstOrDefault(o => o.StudentID == applicationFromView.CurrentUserId);
var instructorApplication = new InstructorApplication
{
BasicInfoGatheredFromProfile = thisStudent,
EducationalBackground = applicationFromView.EducationalBackgrounds as ICollection<EducationalBackground>,
Experience = applicationFromView.Experience,
WillingToTravel = applicationFromView.WillingToTravel
};
this.db.InstructorApplication.Add(instructorApplication);
this.db.SaveChanges();
return this.Redirect("Index");
}
I Know that the problem is with my Jquery script, but i am totally confused now, can anybody please take a look and help me?
Upvotes: 1
Views: 2087
Reputation: 139818
Two things I've noticed in the first round.
dataType: "json"
but dataType is the type of data that you're expecting back from the server, not what your sending. You need to set contentType
JSON.stringify
the data to make the modelbinder happy.Based on the above two your ajax call should like this:
$.ajax({
type: 'POST',
url: instructorUrl,
dataType: "json",
data: JSON.stringify(applicationFromView), //<-- JSON.stringify
contentType: 'application/json; charset=utf-8', //<-- contentType
success: function (data) {
},
error: function (a, b, c) {
alert('A problem ocurred');
}
});
Upvotes: 2