[c#] 자체 참조 루프 감지 됨-WebApi에서 브라우저로 데이터 가져 오기

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.Re‌​ferenceLoopHandling = 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