Deserialize 할 때 json에서 k__BackingField를 제거하는 방법


104

xml 파일을 .net C # 개체로 직렬화 한 후 반환 된 json에서 k_BackingField를 얻습니다.

.net C # 개체에 DataContract 및 DataMember 특성을 추가했지만 json, 클라이언트 쪽에서는 아무것도 얻지 못합니다.

[XmlRoot("person")]
[Serializable]
public class LinkedIn
{
    [XmlElement("id")]
    public string ID { get; set; }

    [XmlElement("industry")]
    public string Industry { get; set; }

    [XmlElement("first-name")]
    public string FirstName { get; set; }

    [XmlElement("last-name")]
    public string LastName { get; set; }
    [XmlElement("headline")]
}

반환 된 json의 예 :

home: Object
<FirstName>k__BackingField: "Storefront"
<LastName>k__BackingField: "Doors"

답변:


45

클래스를 직렬화에 사용할 수있는 경우 자동 속성 구문은 실제로 권장되지 않습니다. 백업 필드가되는 이유는 코드가 컴파일 될 때마다 다를 수있는 컴파일러에 의해 생성됩니다. 이로 인해 클래스가 변경되지 않은 경우에도 비 호환성 문제가 발생할 수 있습니다 (코드를 다시 컴파일하기 만하면 됨).

이 경우 DataMember 속성을 적용하면 문제가 해결 될 것이라고 생각합니다. 그러나 클래스를 직렬화에 사용해야하는 경우 전체 속성 구문을 사용하는 것이 좋습니다.


Lol, 긴 버전을 구현하고 private 필드를 client.home : Object _fName : "Storefront"_headline : "CEO at StorefrontDoors.NET"_id : ""_industry : ""
스택 채우기는 내가하는

21
해당 데이터 계약을 클래스 맨 위에 추가하고 데이터 멤버를 관심있는 각 속성에 추가합니다.
스택 채우기는 내가하는

3
[DataContract] 및 [DataMember]에 대해 @ AlumCloud.Com +1. 추가하는 것을 잊지 마십시오들은 System.Runtime.Serialization
이안 Newland

109

[Serializable]수업에서 제거


2
이제 왜 처음에 [Serializable]이 필요하다고 생각했는지 궁금합니다. 내 Xml 직렬화는없이 작동하고 JSON은없이 작동합니다.
Rhyous 2015 년

11
이것은 WCF 서비스에서 작동하지 않습니다. RESTful 서비스를 사용하여 페이로드를 반환 할 때 [Serializable]을 제거하면 데이터가 생성되지 않습니다. System.Runtime.Serialization을 추가하고 클래스에는 [DataContract]를 사용하고 속성에는 [DataMember]를 사용합니다.
Ian Newland

이 답변과 Ian 의견은 두 경우 모두를 다루는 것 같습니다. WCF 또는 WCF에 대한 질문입니다.
granadaCoder

1
@Rhyous-Web API에서는 [Serializable]이 필요하지 않습니다. Web API는 객체를 직렬화하고 반환 할 것이라는 가정으로 설정되어 있기 때문입니다 (기본적으로 전체 아이디어이기 때문에)-다른 C # 응용 프로그램에서는 일반적으로 직렬화 객체를 구별하는 직렬화 필요
존 스토리를

감사합니다.을 (를 [Serializable]) 사용했기 때문에 지원 필드를 추가하는 것이 도움이되었습니다.
ohmusama

59

기본 WebApi serializer는 "__BackingField :"구문을 c # 자동 속성에 추가합니다. App_Start의 WebConfig에 이것을 추가하여 찾고있을 수있는 깔끔한 json을 얻으십시오.

using Newtonsoft.Json;
...

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();

3
이것은 문제를 해결했습니다. 자동차 속성이 깨끗하다고 ​​생각합니다. 모든 곳에서 지원 필드를 사용하는 것은 어리석은 것처럼 보입니다. 많은 혼란과 때로는 혼란을 야기합니다.
Romesh D. Niriella

이것은 나를 위해 일했습니다. 제 경우에는 WCF 및 ASMX 웹 서비스에서 이미 사용중인 기존 클래스가 있었기 때문에 새 WebAPI 프로젝트를 위해 변경할 수 없었습니다.
samiup

4
질문은 WebApi serializer가 기본적으로 "__BackingField :"를 추가하는 이유입니다.
Teoman shipahi

좋은 해결책. 제 경우에는 [Serializable] 저장을 memcache에 사용해야합니다. 직렬화가 필요합니다.
Bình Nguyễn Quang

2
StackOverflow없이 무엇을 할 수 있습니까? 감사.
camainc

35

[Serializable]전통적인 방법을 사용하여 직렬화 할 수 있도록 표시된 일부 객체가 있지만 Web API와 함께 사용하려면 JSON으로 명확하게 직렬화해야합니다. 로 설정 IgnoreSerializableAttribute하면 trueNewtonsoft.Json이 Microsoft의 직렬화 기처럼 작동하지 않고 대신 공용 속성을 직렬화합니다.

TLDR : WebApiConfig.cs에 다음을 추가하십시오.

((Newtonsoft.Json.Serialization.DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

중재자 : 여러 번 질문 한 질문에 대해 정말 좋은 답변을 삭제하는 대신 중복 질문을 삭제하십시오. 이것은 유효한 질문에 대한 유효한 대답입니다.


3
이것이 정답이되어야합니다. 직렬화를 제거하거나 데이터 계약 및 데이터 멤버 속성을 사용하는 것이 항상 올바른 솔루션은 아닙니다.
Houssam Hamdan

우리 중 많은 사람들이 OP를 포함하여 Webapi 또는 MVVM을 사용하거나 여러분이 무엇을하고 있는지에 대해 그렇지 않습니다. service.svc가있는 일반 SOAP WCF 서비스가있는 경우 app_start 및 webapiconfig는 무엇입니까?
Christian

10

데이터를 노출하는 간단하고 쉬운 방법 우리는 객체의 데이터를 읽기 쉽고 일관된 형식으로 노출해야합니다.


먼저 [Serializable] 제거

    [Serializable]

이제 아래 예제와 같이 클래스 에 [DataContract] 를 추가 하고 속성에 [DataMember] 를 추가합니다.

[DataContract]
public class UserDiscretion : UserReport
{
    [DataMember]
    public String DiscretionCode { get; set; }
    public String DiscretionDescription { get; set; }
}

이 도움말 희망
감사합니다.


1
Web API를 사용하는 경우 DataContract 및 DataMember 특성을 추가 할 필요가 없습니다. 개체를 반환하기 만하면 자동으로 직렬화됩니다.
Jon Story

처음부터 개발을 시작하는 사람이라면 Object 반환 유형을 제공하는 Web API를 사용하는 것이 좋을 것이므로 클라이언트에 노출하기 위해 유형을 캐스팅 할 필요가 없습니다. 그는 기존 응용 프로그램에있는 경우 그러나 @ AlumCloud.com 질문에 대해, 자신의 문제에 대한 해결책은 먼저 삭제가 될 수 있도록 [직렬화]를 누른 다음 [DataContract] 클래스와 추가 [DataMember를] 제안 아래 같은 속성
Nagendra Upwanshi

1
이것은 여러분의 수업에 엄청난 양의 "노이즈"를 추가하고 본질적으로 불필요합니다 (다른 모든 주석 참조). 그러나 실제로이 작업을 수행해야한다고 느낀다면 PostSharp와 같은 것을 사용하여 컴파일 중에 코드를 추가하여 이러한 모든 속성으로 클래스를 복잡하게 만들지 않는 것이 좋습니다.
camainc

7

몇 가지 옵션 :

  1. [Serializable]모델에서 제거

  2. 추가 [DataContract][DataMember]함께 모델에 [Serializable]

  3. 아래 줄 추가 App_Start/WebApiConfig.cs

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();

3

JSON.NET의 경우 도움이 될 수있는 또 다른 솔루션입니다. [Newtonsoft.Json.JsonObject] 속성으로 클래스를 표시하는 것으로 충분할 수 있습니다.

xsd에서 빌드 된 cs 클래스로 작업 중이었고 부분 클래스를 사용하여 일부 속성을 추가했습니다. json 직렬화 후 이러한 속성은 k_BackingField로 표시되었습니다. 다른 답변에서 언급 한 JsonFormatter 설정도 도움이되었지만 더 간단하게 부분 클래스를 [JsonObject] 속성으로 표시했습니다.


2

특성 DataContractJsonSerializer이있는 다른 어셈블리의 클래스와 함께 사용 하고있었습니다 Serializable. 출력에 "k__BackingField"가 포함되었습니다. Serializable다른 어셈블리에서 특성을 제거하면 이 문제가 해결되었습니다. 이유가 확실하지 않습니다.


0

MVC 프로젝트 내에서이 문제를 본다고 가정하면 @ Html.JsonData 사용을 대체하는 것이 매우 간단하다는 것을 알았습니다. 다음은 과거에 저에게 도움이 된 코드 스 니펫입니다.

<input type="hidden" id="Model" value="@Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model))" />

우아하지는 않지만 간단합니다.


0

다음과 같은 클래스에 자체 참조 속성이있을 때이 문제가 발생했습니다.

class Person {
 List<Person> Friends { get; set;}
}

그 결과 그 사람은 자신과 친구였습니다. 결과 집합에 자체 참조 개체가 없는지 확인했습니다. 도움이 되었기를 바랍니다.



0

제 경우에는이 오류가 Newtonsoft.Json 버전에 대한 것이었고, 서버는 6.0.0 버전을 찾고 11.0이 있었으므로 버전 6.0.0을 설치해야했습니다.


-2

친구, 다음과 같은 속성을 선언하지 마십시오.

public String DiscretionCode { get; set; }
public String DiscretionDescription { get; set; }

그러나 오래된 것과 같은 보조 변수를 만듭니다 ....

private String discretionCode;

public String DiscretionCode 
{ 
    get { return discretionCode;}
    set { discretionCode = value; }
}

1
왜? 공명 할 수 있습니까?
Lucenty

@Lucenty는 직렬화 할 때 다음과 같은 JSON을 제공합니다. [{ "discreationCode": "x"}].
아마르 Ameerdeen

그러나 이것이 제가 기대하는 것입니다. 이것이 JSON이 데이터를 직렬화하는 방법입니다. 그리고 보조 변수를 사용하는 코드는 동일한 결과를 얻을 것이라고 생각합니다.
Lucenty

k_BackingField가 추가되어 자동 속성이 직렬화되었음을 나타냅니다. 자동 속성을 속성 및 지원 필드로 리팩터링하면 문제가 사라집니다. 이 스레드에는 더 나은 솔루션이 있다고 생각하지만 작동합니다.
timB33
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.