将List属性与JQuery Ajax中的其他模型属性一起发布到MVC控制器?

时间:2012-06-09 12:52:55

标签: asp.net-mvc asp.net-mvc-3 c#-4.0 jquery

今天我有一个要求,我必须向数据库提交用户的教育详细信息。首先,我将从实体中解释,我在用户和教育表之间有一对多的关系,即用户可以拥有多个教育细节。

我的EducationalBackground模型看起来像这样

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是我的主要模型,它包含一个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; }
    }

我的观点看起来像这样

@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>

我在Views / Shared / EditorTemplate文件夹中包含了一个编辑器模板,以包含educationbackground详细信息,它将充当部分视图以及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>

我写了一个像这样的JQuery脚本,将值发布到控制器,并且能够将所有内容发布到模型中,除了背景细节列表

<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>

我的控制器也是这样的

[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");
}

我知道问题出在我的Jquery脚本上,但我现在完全糊涂了,有人可以看看并帮帮我吗?

1 个答案:

答案 0 :(得分:2)

我在第一轮中注意到的两件事。

  • 您正在设置dataType: "json",但dataType是您期望从服务器返回的数据类型,而不是您发送的数据类型。您需要设置contentType
  • 您需要JSON.stringify数据才能让模型绑定器满意。

根据以上两点,你的ajax调用应该是这样的:

$.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');
        }
    });