78 c# serialization entity-framework json.net asp.net-web-api
我正在使用Entity Framework并且在向浏览器中获取父数据和子数据时遇到问题.这是我的课程:
public class Question
{
public int QuestionId { get; set; }
public string Title { get; set; }
public virtual ICollection<Answer> Answers { get; set; }
}
public class Answer
{
public int AnswerId { get; set; }
public string Text { get; set; }
public int QuestionId { get; set; }
public virtual Question Question { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我使用以下代码返回问题和答案数据:
public IList<Question> GetQuestions(int subTopicId, int questionStatusId)
{
var questions = _questionsRepository.GetAll()
.Where(a => a.SubTopicId == subTopicId &&
(questionStatusId == 99 ||
a.QuestionStatusId == questionStatusId))
.Include(a => a.Answers)
.ToList();
return questions;
}
Run Code Online (Sandbox Code Playgroud)
在C#方面,这似乎有效,但我注意到答案对象有回到问题的参考.当我使用WebAPI将数据提供给浏览器时,我收到以下消息:
'ObjectContent`1'类型无法序列化内容类型'application/json的响应主体; 字符集= UTF-8' .
使用类型"Models.Core.Question"检测属性"问题"的自引用循环.
这是因为问题有答案,而答案有回复问题的参考?我看过的所有地方都建议引用孩子的父母,所以我不知道该怎么办.有人可以给我一些建议.
Sam*_*ach 70
这是因为问题有答案,而答案有回复问题的参考?
是.它无法序列化.
编辑:请参阅Tallmaris的答案和OttO的评论,因为它更简单,可以全局设置.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Re??ferenceLoopHandling = ReferenceLoopHandling.Ignore;
Run Code Online (Sandbox Code Playgroud)
旧答案:
将EF对象Question投影到您自己的中间或DataTransferObject.然后可以成功序列化此Dto.
public class QuestionDto
{
public QuestionDto()
{
this.Answers = new List<Answer>();
}
public int QuestionId { get; set; }
...
...
public string Title { get; set; }
public List<Answer> Answers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
就像是:
public IList<QuestionDto> GetQuestions(int subTopicId, int questionStatusId)
{
var questions = _questionsRepository.GetAll()
.Where(a => a.SubTopicId == subTopicId &&
(questionStatusId == 99 ||
a.QuestionStatusId == questionStatusId))
.Include(a => a.Answers)
.ToList();
var dto = questions.Select(x => new QuestionDto { Title = x.Title ... } );
return dto;
}
Run Code Online (Sandbox Code Playgroud)
Tal*_*ris 54
你也可以在你的尝试Application_Start():
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
Run Code Online (Sandbox Code Playgroud)
它应该解决你的问题,而不需要经历很多箍.
ReferenceLoopHandling.Ignore代替.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
Run Code Online (Sandbox Code Playgroud)
Bon*_*Bon 21
如果使用OWIN,请记住,不再为您提供GlobalSettings!您必须在HttpConfiguration对象中修改此相同设置,该对象将传递给IAppBuilder UseWebApi函数(或您所在的任何服务平台)
看起来像这样.
public void Configuration(IAppBuilder app)
{
//auth config, service registration, etc
var config = new HttpConfiguration();
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//other config settings, dependency injection/resolver settings, etc
app.UseWebApi(config);
}
Run Code Online (Sandbox Code Playgroud)
Moh*_*hin 21
在ASP.NET Core中,修复如下:
services
.AddMvc()
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
Run Code Online (Sandbox Code Playgroud)
如果使用DNX/MVC 6/ASP.NET vNext blah blah,甚至HttpConfiguration会丢失.您必须使用Startup.cs文件中的以下代码配置格式化程序.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().Configure<MvcOptions>(option =>
{
//Clear all existing output formatters
option.OutputFormatters.Clear();
var jsonOutputFormatter = new JsonOutputFormatter();
//Set ReferenceLoopHandling
jsonOutputFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
//Insert above jsonOutputFormatter as the first formatter, you can insert other formatters.
option.OutputFormatters.Insert(0, jsonOutputFormatter);
});
}
Run Code Online (Sandbox Code Playgroud)
ASP.NET Core Web-API(.NET Core 2.0):
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<MvcJsonOptions>(config =>
{
config.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
}
Run Code Online (Sandbox Code Playgroud)