从jQuery发送到控制器的对象列表始终为null

时间:2018-04-12 11:09:44

标签: c# jquery asp.net-core-mvc-2.0

所以这是我班上的模特:

[Table("Question", Schema = "trs")]
public class Question
{

    [Key]
    public int QuestionId { get; set; }

    [ForeignKey("TranType")]
    [Required]
    public int TranTypeId { get; set; }

    [ForeignKey("Company")]

    [Required]
    public int CompanyId { get; set; }

    [Required]
    [StringLength(300)]
    public string Text { get; set; }

    [Required]
    public bool IsActive { get; set; }

    [ForeignKey("QuestionType")]
    public int QTypeId { get; set; }

    public DateTime CreatedDate { get; set; }
    public string CreatedUserId { get; set; }
    public DateTime UpdateDate { get; set; }
    public string UpdateUserId { get; set; }

    public Company Company { get; set; }

    public QuestionType QuestionType { get; set; }

    public TranType TranType { get; set; }

    public ICollection<Answer> Answer { get; set; }

    public ICollection<Grading> Grading { get; set; }
}

这是我的控制器操作,现在它什么也没做,因为我需要首先获取值,这是问题所在:

[Authorize(Roles = "Admin")]
public class QuestionController : Controller
{
    readonly IQuestionRepository questionRepository;
    readonly ICompanyRepository companyRepository;

    public QuestionController(IQuestionRepository qRepository, ICompanyRepository cpnRepository)
    {

        questionRepository = qRepository;
        companyRepository = cpnRepository;

    }
     [HttpPost]
    public ActionResult Save([FromBody] List<Question> qView)
    {
        return View(qView);
    }
}

现在我也试过了:

 [HttpPost]
 public ActionResult Save(List<Question> qView)
 {
        return View(qView);
 }

在这两种情况下我都有问题;在第一个选项中(使用[FromBody])qView为null;在选项2中(没有[FromBody])qView不为null但List为空(Count == 0)。

以下是生成JSON数据的代码:

function Send()
{ 
    var qCounter = parseInt($('#quesCounter').val());
    var listQuestion = [];
    var qView = {};
    qView.Questions = listQuestion;
    for (i = 1; i <= qCounter; i++)
    {
        var question = {};
        var listAnswer = [];
        question.Answers = listAnswer;

        var anCounter = parseInt($('#qtCounter' + i).val());
        var qText = $('#qtText' + i).val();
        var qType = $('#qType' + i).val();

        question["Text"] = qText;
        question["QTypeId"] = qType;

       for (j = 1; j <= anCounter; j++)
        { 
            var answer = {};

            var aText = $('#anText' + i.toString() + j.toString()).val();
            var aCorrect = "";

            if ($('#anCorrect' + i.toString() + j.toString()).prop('checked')) {
                aCorrect = "yes";
            }
            else {
                aCorrect = "no";
            }
            answer["Text"] = aText;
            answer["IsCorrect"] = aCorrect;
            question.Answers.push(answer);
        }

        qView.Questions.push(question);
    }
    $.ajax({
        type: "POST",
        url: "Save", // the method we are calling
        contentType: "application/json",
        data: JSON.stringify(qView),
        //data: JSON.stringify({ 'qView': qView }),
        dataType: "json",
        success: function (result) {
            alert('Yay! It worked!');
            // Or if you are returning something
            alert('I returned... ' + result.WhateverIsReturning);
        },
        error: function (result) {
            alert('Oh no :(');
        }
    });
}

我不知道出了什么问题。

请知道我的问题在哪里?

2 个答案:

答案 0 :(得分:1)

大家好,所以问题就是我以错误的方式调用ajax方法以及客户端映射中的一些属性;我通过这种方式运行方法来修复:

 function Send()
{ 
    var qCounter = parseInt($('#quesCounter').val());
    var listQuestion = [];

    for (i = 1; i <= qCounter; i++)
    {
        var question = {};
        var listAnswer = [];
        question.Answer = listAnswer; //Second problem was here because I was calling here the array Answers when the List<Answer> property on the server side was called Answer.

        var anCounter = parseInt($('#qtCounter' + i).val());
        var qText = $('#qtText' + i).val();
        var qType = $('#qType' + i).val();

        question["Text"] = qText;
        question["QTypeId"] = parseInt(qType);// first problem was here because the property on the Server side was integer and I was sending string.

       for (j = 1; j <= anCounter; j++)
        { 
            var answer = {};

            var aText = $('#anText' + i.toString() + j.toString()).val();
            var aCorrect = "";

            if ($('#anCorrect' + i.toString() + j.toString()).prop('checked')) {
                aCorrect = 1; //third problem was here because true/yes was not recognize so I had to change to 1/0;.
            }
            else {
                aCorrect = 0; //same as above (third problem).
            }
            answer["Text"] = aText;
            answer["IsCorrect"] = aCorrect;
            question.Answer.push(answer);
        }

        listQuestion.push(question);
    }
    $.ajax({
        type: "POST",
        url: "Save", // the method we are calling
        contentType: "application/json",
        data: JSON.stringify(listQuestion),
        success: function (result) {
            alert('worked');
        },
        error: function (result) {
            alert('Something failed');
        }
    });
}

答案 1 :(得分:0)

您是将 contentType 设置为application/json,然后在发送之前字符串化您的数据?你刚才自相矛盾。

你基本上是在说:服务器,我发送给你一个JSON对象。但是,由于您对对象进行了字符串化,因此服务器只会看到一个字符串。这就是服务器无法将数据与模型匹配的原因。

我的2美分

  1. 只要您在客户端构建的JavaScript对象/ JSON与控制器参数中的模型匹配,您就不需要指定contentType[FromBody] - 保持简单。 MVC非常聪明,可以为您进行绑定。您甚至不需要在C#模型中使用小写来表示属性。您甚至可以使用true/false作为布尔值,只要C#模型中的匹配属性定义为bool

  2. 请勿在您的视图/页面上使用您的域/数据模型。创建一个单独的模型(称为视图模型),并在该视图/页面上仅显示您需要显示/使用的内容。您不希望将数据库中的内容公开给全世界。

  3. 请在JavaScript中使用 camelCase 获取变量和函数。你宣布function Send()qView.Questions =question.Answers.push(answer);的方式让我发疯了:p。

  4. 代码示例

    $.ajax({
        type: 'POST',
    
        // Use HTML helper to generate the link instead of hardcode.
        // HTML helper will take care the host, port, and more for you.
        url: '@Url.Action("save", "question", new { area = "" })',
    
        // You usually don't need to specify the contentType.
        // The default 'application/x-www-form-urlencoded' works well for 
        // JSON objects.
        //contentType: "application/json",
    
        // You don't need to stringify the data
        data: { qView: qView },
        //data: JSON.stringify({ 'qView': qView }),
    
        dataType: "json",
        success: function (result) {
            alert('Yay! It worked!');
            // Or if you are returning something
            alert('I returned... ' + result.WhateverIsReturning);
        },
        error: function (result) {
            alert('Oh no :(');
        }
    })
    // I would use .done() here instead of success and error() but 
    // this is just personal taste.
    ;