C# Ajax方法赢得';从控制器传递模型中的ICollection时,无法再工作
我试图列出特定学生的所有C# Ajax方法赢得';从控制器传递模型中的ICollection时,无法再工作,c#,jquery,ajax,asp.net-mvc,C#,Jquery,Ajax,Asp.net Mvc,我试图列出特定学生的所有课程。但是,我在将ICollectionlist发送到Ajax方法时遇到问题。当我这样做时,什么也不会发生,我会收到错误消息(在chrome中): 500(内部服务器错误) 如果我评论/删除Courses=readStudent.Courses(一个课程的ICollection),我的Ajax方法就会按预期工作(没有课程) 我的Ajax代码: $.post("/Home/Test", { "id": id }, function (data) {
课程。但是,我在将ICollection
list发送到Ajax方法时遇到问题。当我这样做时,什么也不会发生,我会收到错误消息(在chrome中):
500(内部服务器错误)
如果我评论/删除Courses=readStudent.Courses
(一个课程的ICollection
),我的Ajax方法就会按预期工作(没有课程)
我的Ajax代码:
$.post("/Home/Test", { "id": id },
function (data) {
if (data) {
$("#testDiv").append($('<div class=\"studentInfo\"> ' +
'<br/> ' +
<b>Student: </b>' + data.FirstName + " " + data.LastName +
'<br/>' +
'<b>School: </b>' + data.SchoolName +
'<br/>' +
'<b>All courses: </b>' +
$.each(data.Courses(function(index, item) { allCources += '<b>' + item + '</b>'; })
+'</div>'));
}
});
课程模型(由EF创建)
公共部分课程{
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2214:DoNotCallOverridableMethodsInConstructors”)]
公共课程(){
this.Students=newhashset();
}
public System.Guid ID{get;set;}
公共字符串名称{get;set;}
公共字符串{get;set;}
公共字符串说明{get;set;}
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2227:CollectionPropertiesShouldBreadOnly”)]
公共虚拟ICollection学生{get;set;}
}
要传递到视图的My ViewModel:
public class StudentVm {
public string FirstName { get; set; }
public string LastName { get; set; }
public string SchoolName { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
公共班级学生虚拟机{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串SchoolName{get;set;}
公共虚拟ICollection课程{get;set;}
}
引发异常是因为课程
包含学生
的属性,JavascriptSerializer
尝试序列化课程
,该课程包含学生
,该课程包含课程
,该课程包含学生
,诸如此类(如果继续,您将耗尽内存)
您只需要返回视图中需要的Course
属性,因此StudentVM
的Courses
属性应该是另一个视图模型的集合,该视图模型只包含您需要的属性,或者只将匿名对象传递回客户端
var student = db.Students.SingleOrDefault(x => x.Id == id);
var results = new
{
FirstName = student.FirstName,
LastName = student.LastName,
SchoolName = student.SchoolName,
Courses = student.Courses.Select(x => new
{
Name = x.Name,
Description = x.Description
})
};
return Json(results);
或者,如果要使用视图模型,则需要
public class StudentVm
{
public string FirstName { get; set; }
....
IEnumerable<CourseVM> Courses { get; set; }
}
public class CourseVM
{
public string Name { get; set; }
public string Description { get; set; }
}
然后在视图中,您需要更改$.each()
循环中的代码,以访问课程的每个属性
$.each(data.Courses(function(index, item) {
allCources += '<b>' + item.Name + '</b>'; // and item.Description
})
$每个(数据)课程(功能(索引,项目){
allCources+=''+item.Name+'';//和item.Description
})
可选地,考虑使用更好的和更强大的序列化数据,它有用于设置循环引用的选项。
这意味着您的<代码>课程= RealSudio。课程抛出一个异常。调试您的代码。也许它是循环引用,您可以选择其中一个当然像“NA”。“我”用实际错误编辑您的问题,并显示您的模型和要包含在视图中的课程的属性。您需要创建匿名对象以避免循环引用(错误是因为课程
包含学生
的属性)这就是为什么您要传递所有模型只选择课程的某些属性您可以显示您的课程吗?您仍然没有显示课程
模型以及要在视图中显示该模型中的哪些属性谢谢。我收到错误消息“无法将类型“system…IEnumerable”隐式转换为“system…ICollection”
。我仅为名称和说明创建了一个CourseVm
。我还更改为公共虚拟ICollection课程{get;set;}”
insideStudentVm
。我遗漏了什么?你没有使用我在答案中显示的代码!没有理由创建单独的视图模型,但我将编辑答案以向你展示如何操作!你删除了StudentVm near result!可能就是这样。我以为这只是课程行。抱歉!请参阅编辑以使用视图模型s(但实际上没有必要这么做-反正它只是要序列化为json-浏览器没有视图模型的概念)它现在可以工作了。很抱歉给您带来不便,我以为我使用了您的代码,但我没有删除StudentVm
,我真傻。非常感谢您的详细解释:)
var student = db.Students.SingleOrDefault(x => x.Id == id);
var results = new
{
FirstName = student.FirstName,
LastName = student.LastName,
SchoolName = student.SchoolName,
Courses = student.Courses.Select(x => new
{
Name = x.Name,
Description = x.Description
})
};
return Json(results);
public class StudentVm
{
public string FirstName { get; set; }
....
IEnumerable<CourseVM> Courses { get; set; }
}
public class CourseVM
{
public string Name { get; set; }
public string Description { get; set; }
}
var student = db.Students.SingleOrDefault(x => x.Id == id);
var results = new StudentVm
{
FirstName = student.FirstName,
LastName = student.LastName,
SchoolName = student.School.Name,
Courses = student.Courses.Select(x => new StudentVM
{
Name = x.Name,
Desription = x.Name
}
};
return Json(results);
$.each(data.Courses(function(index, item) {
allCources += '<b>' + item.Name + '</b>'; // and item.Description
})