WCF는 "set"이없는 속성에서 질식합니다. 해결 방법이 있습니까?


97

서비스 메서드의 결과로 전달하는 클래스가 있으며 해당 클래스에는 가져 오기 전용 속성이 있습니다.

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message { get { return ""; } }
}

서비스 측면에서 예외가 발생합니다.

System.Runtime.Serialization.InvalidDataContractException : 'MyNamespace.ErrorBase'형식의 'Message'속성에 대한 설정된 메서드가 없습니다.

이 속성을 getter로만 가져야하며 사용자가 값을 할당하도록 허용 할 수 없습니다. 사용할 수있는 해결 방법이 있습니까? 아니면 추가 속성이 누락 되었습니까?

답변:


107

Message에 공용 getter를 제공하지만 보호 된 setter를 지정하여 하위 클래스 (및 속임수 때문에 DataContractSerializer) 만 값을 수정할 수 있도록합니다.


그것은 깔끔한 솔루션입니다!
Russell

감사합니다. 유용하게 사용되어 다행입니다! 이것은 실제로이 트릭의 여러 용도 중 하나 일뿐입니다. getter와 setter는 기술적으로 기능하므로 위협적인 IDataContractSurrogate를 사용하지 않고도이 동일한 기술을 사용하여 기본 유형 (아마도 XML의 사용자 지정 시간 형식)의 사용자 지정 직렬화를 제공 할 수 있습니다.
rh.

28
비공개로 설정할 수도 있습니다. Serializer는 비공개, 공개, 보호, 내부 또는 내부 보호 여부를 신경 쓰지 않습니다.
Abel

8
와 세터 만들기throw new NotSupportedException()
Simon_Weaver

2
갖는 private set;당신이 사용하는 경우 작업을 [DataContract]하고 [DataMember]. 생략하면 public set;.
user276648 jul.

12

값을 업데이트 할 필요가없는 경우에도 WCFSerializer에서 setter를 사용하여 개체를 역 직렬화하고 값을 다시 설정합니다.

이것은 당신이 추구하는 것입니다 : WCF DataContracts


1
그래서 내가 문제를 극복하는 유일한 방법은 그것을 재산 대신 방법으로 만드는 것입니까? 다시 말하지만, 나는이 속성에 "설정"을 허용 할 수 없습니다
Andrey

메서드 (예 : GetMessage () {return "";})로 만들 수 있습니다. 대신 WCF Serializer에이를 무시하도록 지시 할 수 있습니다. 내가 찾을 수있는 것을보고 알려 드리겠습니다.,
Russell

1
이 stackoverflow 질문은 머리에 못을 박았습니다. stackoverflow.com/questions/172681/wcf-datacontracts
Russell

11
[DataMember(Name = "PropertyName")]
public string PropertyName
{
    get
    {
        return "";
    }
    private set
    { }
}

5

getter 만있는 경우 속성을 직렬화해야하는 이유는 무엇입니까? 읽기 전용 속성에 대한 DataMember 특성을 제거 할 수있는 것처럼 보이며 serializer는 속성을 무시합니다.


3
파생 된 속성 (예 : ID 속성에서 계산되는 URL 속성)을 영구 저장소 (예 : 데이터베이스)로 직렬화하는 것은 실제로 의미가 없습니다 (예 : 데이터베이스). API 요청에 의해 반환되는 표현 (예 : JSON 또는 XML)
Florian Winter

4

당신은 "아무것도하지 않는"세터를 가질 수 없습니까 ??

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message 
  {
      get { return ""; } 
      set { }
  }
}

아니면 DataContract 시리얼 라이저도 그럴까요 ??


14
그것은 barf가 아닙니다. 저는 클라이언트 API를 사용하는 개발자가 속성에 물건을 할당 할 수 있다고 생각하게하고 싶지 않았습니다.
Andrey

2

DataMember 속성이있는 속성에는 항상 설정이 필요합니다. DataContract 구성원은 항상 값을 할당 할 수 있으므로 클라이언트 응용 프로그램에서 simmilar 개체를 다시 작성해야합니다.


2

ASP.NET MVC에서이 문제가 발생했으며 JSON 출력 항목의 이름을 제어 할 수 있도록 DataContractSerializer를 사용하고 싶습니다. 결국 저는 serializer를 .NET을 통해 setter (DataContractSerializer가 지원하지 않음) 및 속성 이름 제어 (ASP.NET MVC의 기본 제공 JSON serializer가 지원하지 않음)가없는 속성을 지원하는 JSON.NET으로 전환했습니다 [JsonProperty(PropertyName = "myName")].


2

실행 가능한 옵션 인 ErrorBase경우 기본 클래스로 사용하는 대신 다음과 같이 정의하십시오.

    public interface IError
    {
        string Message
        {
            [OperationContract]
            get;

            // leave unattributed
            set;
        }
    }

이제 setter가 존재하더라도 WCF 채널을 통해 클라이언트에 액세스 할 수 없으므로 마치 개인용 인 것처럼 보입니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.