WCF : 설정하지 않고 읽기 전용 DataMember 속성을 노출합니까?
[DataContract]를 통해 클라이언트 측에서 사용할 수있는 서버 측 클래스가 있습니다. 이 클래스에는 속성을 통해 사용할 수있는 읽기 전용 필드가 있습니다. 그러나 get과 set없이 [DataMember] 속성을 추가 할 수없는 것 같기 때문에 그렇게 할 수 없습니다.
그래서-setter없이 [DataMember] 속성을 갖는 방법이 있습니까?
[DataContract]
class SomeClass
{
private readonly int _id;
public SomeClass() { .. }
[DataMember]
public int Id { get { return _id; } }
[DataMember]
public string SomeString { get; set; }
}
아니면 솔루션이 [DataMember]를 필드로 사용 합니까 (예 : 여기에 표시된 것처럼 )? 이 작업도 시도했지만 필드가 읽기 전용인지 신경 쓰지 않는 것 같습니다 ..?
편집 : 이렇게 해킹하여 읽기 전용 속성을 만드는 유일한 방법입니까? (아니요-이거하고 싶지 않아 ...)
[DataMember]
public int Id
{
get { return _id; }
private set { /* NOOP */ }
}
"서버 측"클래스는 실제로 클라이언트가 "사용 가능"하지 않습니다.
이것은 데이터 계약에 따라 클라이언트가 서비스의 XML 스키마에서 별도의 새로운 클래스를 생성합니다. 그것은 할 수없는 그 자체 서버 측 클래스를 사용!
XML 스키마 정의에서 새 클래스를 다시 만들지 만 해당 스키마에는 가시성 또는 액세스 수정 자와 같은 .NET 특정 항목이 포함되어 있지 않습니다. 결국 XML 스키마 일뿐입니다. 클라이언트 측 클래스는 와이어에서 동일한 "풋 프린트"를 갖는 방식으로 생성됩니다. 예를 들어 기본적으로 동일한 XML 형식으로 직렬화됩니다.
당신은 할 수 없습니다 "전송".NET의 특정 노하우 표준 SOAP 기반의 서비스를 통해 클래스에 대해 - 모든 후, 당신이 주변에 전달하는 모든되는 메시지를 직렬화하지 - 어떤 클래스를!
"SOA의 네 가지 원칙"(Microsoft의 Don Box에서 정의)을 확인하십시오.
- 경계는 명시 적입니다.
- 서비스는 자율적입니다.
- 서비스는 클래스가 아닌 스키마와 계약을 공유합니다.
- 호환성은 정책을 기반으로합니다.
요점 # 3-서비스는 클래스가 아니라 스키마와 계약을 공유합니다. 데이터 계약에 대한 인터페이스와 XML 스키마 만 공유합니다. 그게 전부입니다. .NET 클래스는 없습니다.
속성이 아닌 필드에 DataMember 속성을 넣습니다.
WCF는 캡슐화를 모릅니다. 캡슐화는 SOA 용어가 아니라 OOP 용어입니다.
즉,이 필드는 클래스를 사용하는 사람들에게만 읽기 전용이됩니다. 서비스를 사용하는 모든 사람은 자신의 필드에 대한 전체 액세스 권한을 갖게됩니다.
Silverlight로 전달하고 싶은 서비스 계층의 클래스에 몇 가지 속성이 있습니다. 나는 완전히 새로운 수업을 만들고 싶지 않았습니다.
실제로 '권장'되는 것은 아니지만, 이것은 Total
속성을 silverlight (시각적 데이터 바인딩만을 위해) 로 넘겨주는 두 가지 악 중 적은 것으로 보였습니다 .
public class PricingSummary
{
public int TotalItemCount { get; set; } // doesnt ideally belong here but used by top bar when out of store area
public decimal SubTotal { get; set; }
public decimal? Taxes { get; set; }
public decimal Discount { get; set; }
public decimal? ShippingTotal { get; set; }
public decimal Total
{
get
{
return + SubTotal
+ (ShippingTotal ?? 0)
+ (Taxes ?? 0)
- Discount;
}
set
{
throw new ApplicationException("Cannot be set");
}
}
}
이를 달성하는 방법이 있습니다. 그러나이 답변에 인용 된 다음 원칙을 직접 위반한다는 점에 유의하십시오 .
"3. 서비스는 클래스가 아닌 스키마와 계약을 공유합니다."
이 위반 사항이 귀하와 관련이없는 경우 다음과 같이하십시오.
서비스 및 데이터 계약을 별도의 (이동 가능한) 클래스 라이브러리로 이동합니다. (이 어셈블리를 호출합시다
SomeService.Contracts
.) 다음은 변경 불가능한[DataContract]
클래스를 정의하는 방법입니다 .namespace SomeService.Contracts { [DataContract] public sealed class Foo { public Foo(int x) { this.x = x; } public int X { get { return x; } } [DataMember] // NB: applied to the backing field, not to the property! private readonly int x; } }
참고
[DataMember]
배면 필드에 적용되고 있지 대응하는 판독 전용 속성.서비스 응용 프로그램 프로젝트 (내가라고 함
SomeService.Web
)와 클라이언트 프로젝트 (내가라고 함SomeService.Client
) 모두에서 계약 어셈블리를 참조합니다 . 이로 인해 솔루션 내에서 다음과 같은 프로젝트 종속성이 발생할 수 있습니다.다음으로 서비스 참조를 클라이언트 프로젝트에 추가 할 때 "재사용 유형"옵션이 활성화되어 있는지 확인하고 계약 어셈블리 (
SomeService.Contracts
)가 여기에 포함 되는지 확인합니다 .
Voilà! Visual Studio, instead of generating a new Foo
type from the service's WSDL schema, will reuse the immutable Foo
type from your contract assembly.
One last warning: You've already strayed from the service principles cited in that other answer. But try not to stray any further. You might be tempted to start adding (business) logic to your data contract classes; don't. They should stay as close to dumb data transfer objects (DTOs) as you can manage.
Define the Service contract (Interface) Before implementing the contract using the class.
참고URL : https://stackoverflow.com/questions/1873741/wcf-exposing-readonly-datamember-properties-without-set
'developer tip' 카테고리의 다른 글
IntelliJ에서 한 발 뒤로 물러나는 방법은 무엇입니까? (0) | 2020.12.09 |
---|---|
PostgreSQL에서 암호의 데이터 유형은 무엇입니까? (0) | 2020.12.09 |
CSS 전환 자동 높이가 작동하지 않음 (0) | 2020.12.08 |
psql을 사용하여 SSL 모드에서 postgresql에 연결 (0) | 2020.12.08 |
dynamic_cast를 사용하려고 할 때 "소스 유형이 다형성이 아닙니다." (0) | 2020.12.08 |