2009-08-12 3 views
17

ASP.NET MVC 앱을 개발하는 동안 JsonResult 액션에서 "객체를 직렬화하는 동안 순환 참조가 감지되었습니다"라는 예외가 발생하는 곳을 몇 개 발견했습니다.ASP.NET MVC에서 JSON 직렬화를 방지하려면 어떻게해야합니까?

현재로서는 문제의 참조를 제거하고 있지만 이상적으로 JSON serializer가 속성을 무시하는 것으로 표시하고 싶습니다.

누구든지 내가 어떻게 할 수 있을지 제안 할 수 있습니까?

+0

어떤 시리얼 라이저를 사용하고 있습니까? –

+0

JsonResult가 반환 형식이므로 ASP.NET MVC 1.0의 컨트롤러 클래스에서 기본적으로 사용되는 serializer를 사용하고 있다고 가정합니다. – JMP

+0

이것은 JavaScriptSerializer입니다. – womp

답변

28

[ScriptIgnore]해야합니다.

+2

JsonResult가 JavaScriptSerializer를 내부적으로 사용하기 때문에 이것이 작동합니다. – womp

+3

다른 사람에게주는주의 사항 : System.Web.Extensions 어셈블리에 대한 참조를 적어도 .NET 4에서 사용할 수 있도록 추가해야 할 수 있습니다. – Jacob

+4

System.Web.Script.Serialization.ScriptIgnore –

13

나는 일반적으로 복잡한만을위한 임시 'inbetween'객체를 생성하여 직렬화하기 위해 최선 개체를 발견했습니다 : 예를 들어

을 평가를 위해 내가 할 다음을. 실제로 ASPX 모델 페이지의 코드 숨김에서이 ​​작업을 수행합니다.

이렇게하면 멋진 JSON 개체가 생성됩니다. 내 모델을 리팩토링 할 수 있다는 것을 알게 될 것이며 페이지는 여전히 작동 할 것입니다. 데이터 모델과 페이지 간의 추상화 계층. 나는 내 컨트롤러가 JSON을 가능한 많이 알아야한다고 생각하지 않지만 ASPX '코드 숨김'은 확실히 할 수있다. 내 ASPX에서

/// <summary> 
/// Get JSON for testimonials 
/// </summary> 
public string TestimonialsJSON 
{ 
    get 
    { 
     return Model.Testimonials.Select(
      x => new 
      { 
       testimonial = x.TestimonialText, 
       name = x.name 
      } 
      ).ToJSON(); 
    } 
} 

난 그냥 블록에서 다음을 수행

var testimonials = <%= TestimonialsJSON %>; 

// oh and ToJSON() is an extension method 
public static class ObjectExtensions 
{ 
    public static string ToJSON(this Object obj) 
    { 
     return new JavaScriptSerializer().Serialize(obj); 
    } 
} 

내가 그것을 가지고 ...이 제안에 대한 반발에 대한 준비가 ...

나 ' 뷰에 대한 모델을 다시 포맷하기 만하면 데이터에 액세스하지 못합니다. 이것은 '컨트롤러 모델'논리가 아닌 '보기 모델'논리입니다.

+2

+1. 처음에는 "여러 모델을 생성하고 싶지 않습니다"라는 반발을하고 싶었지만 "보기 모델"은 나에게 어떤 의미를 갖기 시작했습니다. 비즈니스 논리 모델을 만들고 왜 모델을 만들어 보지 않을까요? 논리? 훌륭한! 내 구체적인 상황에 대한 대답이 아니지만, upvote 가치가있는 def. – JMP

+0

여러 모델 중 하나를 만들고 싶지 않습니다! 이것은 다른 클래스 (여기서는 불필요 함)를 만들지 않고도 그렇게하는 가장 쉬운 방법입니다. 모델은 데이터와 데이터 만 표시해야하며 데이터가 표시되는 방식이 아니며 항상 실용적인 것은 아니지만 다른 기술에 대한 뷰 변경 사항 또는 여러 다른 뷰 (ajax)를 제공해야하는 뷰와 모델 간의 결합을 최소화해야합니다./flash/plain html) –

+0

동일한 기본 모델에 대해 몇 가지 JSON 직렬화가 필요할 수있는 경우이 접근 방식을 좋아합니다. –

2

JSON.NET을 사용하는 것이 좋습니다. 순환 참조를 직렬화 할 수 있으며 훨씬 많은 직렬화 옵션을 제공합니다.

2

시몬이 말한 내용. 코드 가중치를 제어하기 위해 약간의 AutoMapper 조치를 추가하십시오.

1

내가 찾은 가장 깨끗한 접근법은 클래스에 [DataContract]와 직렬화하려는 속성의 [DataMember]를 함께 사용하는 것입니다. DataContract 특성은 다양한 serializer에 DataMember 특성이없는 속성을 무시하도록 지시합니다.

ScriptIgnoreAttribute를 사용하는 것에 비해 두 가지 주요 이점이 있습니다. 첫째, System.Web.Extensions 어셈블리에 대한 종속성이 없습니다. 둘째, JSON뿐만 아니라 다른 유형의 직렬화에서도 작동합니다. 예를 들어 MVC 4에서 새 웹 API를 사용하는 경우 DataContract/DataMember 방식은 XML serializer에서도 사용할 수 있습니다.

엔티티가 공유 라이브러리에 저장되어 다양한 프로젝트에서 재사용되는 시나리오를 고려하십시오. System.Web.Extensions에 의존하지 않고 직렬화 규칙을 대략적으로 설명하고자합니다. JSON, XML 등

관련 문제