C # 익명 형식을 JSON 문자열로 직렬화하려면 어떻게합니까?


162

익명 유형을 JSON으로 직렬화하기 위해 다음 코드를 사용하려고합니다.

var serializer = new DataContractJsonSerializer(thing.GetType());
var ms = new MemoryStream();
serializer.WriteObject(ms, thing);
var json = Encoding.Default.GetString(ms.ToArray()); 

그러나 이것이 실행될 때 다음 예외가 발생합니다.

'<> f__AnonymousType1`3 [System.Int32, System.Int32, System.Object []]'유형은 직렬화 할 수 없습니다. DataContractAttribute 특성으로 표시하고 DataMemberAttribute 특성으로 직렬화하려는 모든 멤버를 표시하십시오. 지원되는 다른 유형에 대해서는 Microsoft .NET Framework 설명서를 참조하십시오.

익명 유형에 속성을 적용 할 수 없습니다 (아는 한). 이 직렬화를 수행하는 다른 방법이 있습니까, 아니면 뭔가 빠졌습니까?

답변:


159

DataContractJsonSerializer 대신 JavaScriptSerializer를 사용해보십시오.

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);

17
트랙백, SP1에서 더 이상 사용되지 않는 것 같습니다.
Biswanath

7
너무 절대적인 것은 MVC를 포함한 많은 새로운 Microsoft 프레임 워크에서 사용되고있는 것으로 보입니다. aspnet.codeplex.com/SourceControl/changeset/view/21528#266491
Nick Berardi

1
이 비 ASP.net 프로젝트 (콘솔 응용 프로그램)를 어떻게 포함합니까?
Alxandr

4
@Alxandr : 명령문 을 참조 System.Web.Extensions.dll하고 추가해야 using System.Web.Script.Serialization;합니다.
randomguy

1
@randomgui 문제는 프로젝트 출력 유형이 클라이언트 프로파일로 설정되었습니다.
Alxandr

75

다른 사람들이 언급했듯이 Newtonsoft JSON.NET 은 좋은 옵션입니다. 다음은 간단한 JSON 직렬화의 특정 예입니다.

return JsonConvert.SerializeObject(
    new
    {
       DataElement1,
       SomethingElse
    });

나는 그것이 매우 유연하고 다재다능한 라이브러리라는 것을 알았습니다.


14

내 ServiceStack JsonSerializer 는 현재 가장 빠른 .NET JSON 직렬 변환기 입니다. DataContract, 모든 POCO 유형, 인터페이스, 익명 유형을 포함한 후기 바인딩 된 객체 등의 직렬화를 지원합니다.

기본 예

var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = customer.ToJson();
var fromJson = json.FromJson<Customer>(); 

참고 : 다른 JSON 직렬 변환기보다 최대 40x-100x 느리기 때문에 벤치 마크에서 제외해야하므로 성능이 중요하지 않은 경우 Microsoft JavaScriptSerializer 만 사용하십시오 .


7
MVC3 스택에서 MS JavaScriptSerializer를 사용하여 소량의 데이터로 객체를 직렬화하고 있습니다. 이 경우 매우 빠르며 필요한 작업을 수행하는 데 밀리 초도 걸리지 않습니다. DB 쿼리 자체는 50x-100x 더 오래 걸리므로 실제로는 병목 현상이 심각하지 않습니다.
Brian

2
조기 최적화는 ... 잘 알고 있습니다.
Mathias Lykkegaard Lorenzen

1
"가장 빠른 .NET JSON serializer"링크는 404입니다! 또한이 답변은 5 1/2 세 이상입니다. 다양한 .NET JSON 시리얼 라이저의 성능에 대한 업데이트가 있습니까?
ErikE

11

오늘은 serializer가 내장되어 있어야하며 swagger + 속성을 사용하여 소비자에게 엔드 포인트 및 반환 데이터를 알리는 데 도움이 될 수 있다고 주장합니다.


익명 유형을 직렬화해서는 안된다고 주장합니다 . 나는 여기서 유혹을 안다. 브라우저의 자바 스크립트와 같이 느슨하게 유형이 지정된 환경에서 사용될 일부 폐기 유형을 빠르게 생성하려고합니다. 여전히 실제 유형을 만들고 Serializable로 장식합니다. 그런 다음 웹 메소드를 강력하게 입력 할 수 있습니다. 이것은 Javascript에 대한 하나의 iota와 관련이 없지만 메소드에 자체 문서를 추가합니다. 합리적으로 숙련 된 프로그래머라면 함수 서명을보고 "아, 이것은 Foo 타입입니다! JSON에서 어떻게 보일지 알고 있습니다."라고 말할 수 있습니다.

그렇게 말하면 JSON.Net 을 사용하여 직렬화를 시도 할 수 있습니다 . 그것이 효과가 있을지 모르겠다


3
JSON.Net은 잘 작동합니다. 나는 당신이하지 말아야한다고 주장 할 것이다 :), 나는 그것이 합법적이라고 생각한다.
Aprilchild

2
MVC에서 사용되는 "throw away"유형을 본 후 몇 가지 강력한 용도를 볼 수 있습니다. 나는 그것이 .Net 도구 상자에있는 매우 편리한 도구라고 생각합니다.
Matthew Whited

12
이것은 특히 소비 전용 유형의 경우에 내가 부드럽게 한 요점입니다. 그러나 객체가 서버로 돌아가거나 둘 이상의 위치에서 사용되는 경우 유형을 만들면 문제가 줄어 듭니다.
Jason Jackson

DataContract 스타일 역 직렬화는 다형성 유형을 잘 처리하지 못합니다. 자신의 디시리얼라이저를 작성해야합니다. 코드 유지 보수가 너무 많습니다.
micahhoover 2016 년

익명 유형을 직렬화하는 것이 유용한 사용 사례는 웹 API에 대한 단위 테스트입니다.
howcheng

9

내가 찾은 가장 빠른 방법은 다음과 같습니다.

var obj = new {Id = thing.Id, Name = thing.Name, Age = 30};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(obj);

네임 스페이스 : System.Web.Script.Serialization.JavaScriptSerializer


2
그리고 역 직렬화 :. . dynamic myObject = JsonConvert.DeserializeObject <동적> (출력); . . 참조 : Newtonsoft.json.dll
i31nGo

2

Newtonsoft.Json을 사용할 수 있습니다.

var warningJSON = JsonConvert.SerializeObject(new {
                warningMessage = "You have been warned..."
            });

1

웹 서비스에 이것을 사용한다고 가정하면 클래스에 다음 속성을 적용하면됩니다.

[System.Web.Script.Services.ScriptService]

그런 다음 Json을 리턴해야하는 각 메소드에 다음 속성이 있습니다.

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

메소드의 리턴 유형을 "객체"로 설정하십시오.


표준 ASP 웹 서비스의 경우 [ScriptMethod (ResponseFormat = ResponseFormat.Json)]이 메소드에 필요하지 않은 경우 [WebMethod]가 수행합니다. 또한 리턴 유형을 오브젝트로 설정해서는 안되며, 비 복잡한 (즉, 직렬화 될 수있는) 유형으로 강력하게 유형을 지정할 수 있어야합니다.
ROW1

-1
public static class JsonSerializer
{
    public static string Serialize<T>(this T data)
    {
        try
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream();
            serializer.WriteObject(stream, data);
            string jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
            stream.Close();
            return jsonData;
        }
        catch
        {
            return "";
        }
    }
    public static T Deserialize<T>(this string jsonData)
    {
        try
        {
            DataContractJsonSerializer slzr = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
            T data = (T)slzr.ReadObject(stream);
            stream.Close();
            return data;
        }
        catch
        {
            return default(T);
        }
    }
}

이것은 질문에 따라 익명 유형을 직렬화하지 않습니다
Mark Sowul
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.