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; }
}
다음 코드를 사용하여 질문 및 답변 데이터를 반환하고 있습니다.
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;
}
C # 측면에서 이것은 작동하는 것처럼 보이지만 대답 개체에 질문에 대한 참조가 있음을 알 수 있습니다. WebAPI를 사용하여 데이터를 브라우저로 가져올 때 다음 메시지가 표시됩니다.
‘ObjectContent`1’유형이 콘텐츠 유형 ‘application / json;에 대한 응답 본문을 직렬화하지 못했습니다. charset = utf-8 ‘입니다.
유형이 ‘Models.Core.Question’인 속성 ‘question’에 대해 자체 참조 루프가 감지되었습니다.
질문에 답변이 있고 답변에 질문에 대한 참조가 있기 때문입니까? 내가 본 모든 장소는 아이의 부모에 대한 언급을 제안하므로 어떻게 해야할지 모르겠습니다. 누군가 나에게 이것에 대한 조언을 줄 수 있습니까?
답변
질문에 답변이 있고 답변에 질문에 대한 참조가 있기 때문입니까?
예. 직렬화 할 수 없습니다.
편집 : Tallmaris의 답변과 OttO의 의견을 참조하십시오. 더 간단하고 전역 적으로 설정할 수 있습니다.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
이전 답변 :
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; }
}
다음과 같은 것 :
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;
}
답변
다음에서 시도해 볼 수도 있습니다 Application_Start()
.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
많은 후프를 거치지 않고 문제를 해결해야합니다.
편집 : 아래 OttO의 의견에 따라 ReferenceLoopHandling.Ignore
대신 사용하십시오 .
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
답변
OWIN을 사용하는 경우 더 이상 GlobalSettings가 필요하지 않습니다! IAppBuilder UseWebApi 함수 (또는 사용중인 서비스 플랫폼)에 전달되는 HttpConfiguration 개체에서 이와 동일한 설정을 수정해야합니다.
이렇게 보일 것입니다.
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);
}
답변
ASP.NET Core에서 수정 사항은 다음과 같습니다.
services
.AddMvc()
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
답변
DNX / MVC 6 / ASP.NET vNext를 사용하는 경우 어쩌구 저쩌구, 심지어 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);
});
}
답변
ASP.NET Core 웹 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;
});
}
답변
이것을 사용하여 :
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore
나를 위해 일하지 않았다. 대신 테스트를 위해 모델 클래스의 새롭고 단순화 된 버전을 만들었는데 제대로 돌아 왔습니다. 이 기사는 EF에서 훌륭하게 작동했지만 직렬화 할 수 없었던 내 모델에서 겪었던 몇 가지 문제에 대해 설명합니다.
http://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-4