2011-09-16 2 views
7

에서 객체를 인스턴스화 :WCF I는 다음과 같이 두 개의 클래스가를 DataContract 생성자

[DataContract] 
public class Address 
{ 
    [DataMember] 
    public string Line1 
    [DataMember] 
    public string Line2 
    [DataMember] 
    public string City 
    [DataMember] 
    public string State 
    [DataMember] 
    public string Zip 
} 

[DataContract] 
public class Customer 
{ 
    public Customer() 
    { 
     CustomerAddress = new Address(); 
    } 

    [DataMember] 
    public string FirstName 
    [DataMember] 
    public string LastName 
    [DataMember] 
    public Address CustomerAddress 
} 

내가 고객 클래스를 사용하여 내 서비스의 프록시를 생성하는 경우 어떻게됩니까? 내가 그 개념을 올바르게 이해한다면, 나는 Customer 클래스의 생성자가 클라이언트 측에서 호출되지 않을 것이고 그것이 다른 행동을 줄 것이라고 생각한다.

Customer 클래스의 해당 생성자를 없애고 Address 유형의 CustomerAddress 속성을 갖고있어 벙어리 DTO 개체로 작동하도록하려면 어떻게해야합니까?

사람들이이 상황을 피하기 위해 사용하는 일반적인 지침이나 모범 사례는 무엇입니까?

답변

6

기본값 인 DataContractSerializer을 사용하여 객체를 직렬화하면 생성자가 직렬화되지 않으며 객체에 직렬화되어있는 논리는 객체가 직렬화 될 때 클라이언트에 의해 호출되지 않습니다.

생성자 논리를 제거하고 중첩 된 Address 클래스를 채우는 것에 대한 질문은 DataContractSerializer에 의해 처리됩니다. 나는 다음과 같은 코드가있는 경우 : 다음

Customer c = new Customer() { 
    FirstName = "David", 
    LastName = "Hoerster", 
    CustomerAddress = new Address() { 
    Line1 = "1 Main Street", 
    City = "Smallville", 
    State = "AA", 
    Zip = "12345" 
    } 
}; 

Customer 객체가 Address 정보와 함께 제대로 직렬화됩니다, 서비스 방법에서 그를 반환합니다. 생성 된 클라이언트의 프록시는 Address에 대해 알게되고 Customer 객체를 제대로 구성하기 위해 서비스 메소드에서 오는 스트림을 비 직렬화 할 수 있습니다. 귀하의 Customer은 더미 DTO가 될 것입니다 - 논리가없고 속성 만 있습니다.

WCF 직렬화에서 Aaron Skonnard의 MSDN article을 확인하십시오. 여기에서 그는 DataContractSerializer에 대해 이야기합니다.

[DataContract] 
public class Customer 
{ 
    // empty default constructor 
    public Customer() 
    { 
    } 

    [DataMember] 
    public string FirstName 
    [DataMember] 
    public string LastName 
    [DataMember] 
    public Address CustomerAddress 
} 

귀하의 구현 세부 사항은 이월되지 않습니다처럼

0

어셈블리에서 모든 데이터 계약 클래스를보다 잘 정의하고 초기화 동작을 공유 할 수 있도록 서버 프로젝트 및 클라이언트 프로젝트를 어셈블리에 참조하는 것이 좋습니다. 서비스 참조를 생성 할 때 기존 데이터 계약 클래스를 사용하도록 코드 생성기에 지시 할 수 있습니다.

1

은 (는 svcutil을 사용하거나 "서비스 참조를 추가") 클라이언트를 생성 경우, 생성 된 DataContract는 볼 것이다. 생성 된 것은 WSDL로 들어가는 것인데, 이것은 단지 [DataMember] 속성입니다.

원본 질문에 "프록시를 생성하면 어떻게됩니까?"라고 언급합니다. ".


이 개체가 서버에서 클라이언트로 전송되는 경우 클라이언트에 보내기 전에 CustomerAddress를 항상 초기화 할 수 있습니다. 실제로 원래 코드가 서버에 있으면 해당 생성자가 실행되고 WCF는 CustomerAddress을 serialize하고 기본적으로 null을 보내지 않습니다 (생성자 다음에 null로 다시 설정하지 않는 한).

당신은 당신이 수, 클라이언트는 항상 당신에게 CustomerAddress 보내도록 그것을 확인하려면 :

  • 가 null의 서버 검사가 필요에 따라
  • if(x.CustomerAddress == null) x.CustomerAddress = new Address(); 같은 DataMember를 표시, 클라이언트가 아무 것도 전달하지 않은 경우 서버는 오류를 반환합니다. [DataMember(IsRequired=true)] public Address CustomerAddress;

그렇지 않으면 생성을 강제로 수행 할 방법이 없다고 생각합니다. d WCF 클라이언트가 해당 필드를 초기화합니다.

관련 문제