2009-03-16 4 views
8

새 응용 프로그램에 WCF를 사용하여 구현하려는 기존 SOAP 웹 서비스 인터페이스가 있습니다. 이것은 하나의 작은 세부 사항을 제외하고는 잘 작동하는 것 같습니다. 함수의 반환 유형의 XML 네임 스페이스는 웹 서비스 자체의 XML 네임 스페이스와 달라야합니다. 그리고 저의 삶을 위해, 나는 그것이 작동하도록 할 수 없습니다.WCF XML serialization을 사용자 지정하는 방법

작은 샘플 프로젝트에서 같은 문제를 재현했습니다. WCF 인터페이스 :

[XmlSerializerFormat] 
[ServiceContract(Namespace = "urn:outer-namespace")] 
public interface IService1 
{ 
    [OperationContract] 
    MyClass DoStuff(int value); 
} 

[Serializable] 
public class MyClass 
{ 
    [XmlElement(ElementName = "DataString")] 
    public string MyString { get; set; } 
} 

웹 서비스 구현 :

이 웹 서비스로부터의 응답이 다음과 같이 직렬화
public class Service1 : IService1 
{ 
    public MyClass DoStuff(int value) 
    { 
     return new MyClass { MyString = "Wooh!" }; 
    } 
} 

: 우리가 (생략 SOAP 물건)

<DoStuffResponse xmlns="urn:outer-namespace"> 
    <DoStuffResult> 
     <DataString>Wooh!</DataString> 
    </DoStuffResult> 
    </DoStuffResponse> 

그러나 원하는 <DoStuffResult>은 xmlns = "urn : inner-namespace"가되어야합니다.

나는 인터페이스 함수 나 웹 서비스 함수에 [return : XmlElement (...)]를 추가하려고 시도했지만 취하지는 않습니다. 또한 MyClass 클래스 정의에서 [XmlType] 또는 [XmlRoot]가 작동하지 않습니다.

누구나 WCF 웹 서비스 함수의 반환 값인 객체의 직렬화 된 XML 네임 스페이스 (또는 요소 이름)를 변경하는 방법을 알고 있습니까?

답변

3

XML 직렬화 (또는 더 나은) 데이터 계약 정의 속성을 사용하여 네임 스페이스를 정의하십시오.

XML 직렬화 :

[Serializable, XmlRoot(namespace="http://example.com/eg1")] 
public class MyClass { 
    [XmlElement(ElementName = "DataString")] 
    public string MyString { get; set; } 
} 

데이터 계약 직렬화와 함께 : 욕망, 메시지 주위에 SOAP 래퍼의 네임 스페이스를하지 설정하는 것입니다 때문에

[DataContract(Namespace="http://example.com/eg2")] 
public class MyClass { 
    [DataMember] 
    public string MyString { get; set; } 
} 

편집

첫 번째 의견을 바탕으로, 위에서 작동하지 않습니다 메시지 자체에.

OperationContractAttribute은 네임 스페이스를 제어 할 수 없으며 메서드 수준에서 다른 WCF 특성을 볼 수 없습니다.

두 가지 가능성 : (1) 추상화 수준을 삭제하고 메시지 계약을 사용하면 충분히 제어 할 수 있습니다. (2) 서비스의 현재 WSDL (svcutil.exe 사용)을 가져 와서 원하는 네임 스페이스를 얻기 위해 수동으로 조정 한 다음 svcutil.exe을 다시 사용하여 결과 코드를 확인합니다.

+0

이미 질문에 명시된 것처럼, 나는 XmlRoot 속성을 추가 시도하고 그것은 작동하지 않았다. 네임 스페이스는 MyClass 내의 필드에만 추가되지만 MyClass 자체에는 추가되지 않습니다. DataContract도 작동하지 않으며 이름 바꾸기 때문에 XmlSerializer를 선호하므로 순서가 중요하지 않습니다. –

+0

svcutil을 사용했지만 serializer를 지정하지 않고 XmlSerializer를 사용하여 MessageContract와 ServiceContract의 조합을 생성했습니다. 따라서 하나 또는 두 개의 래퍼가 있으며 XML 특성을 사용하여 모든 작업을 수행 할 수 있습니다. –

1

수십 권의 추천 솔루션을 검색하고 시도한 후에; 마침내 WCF가 웹 서비스 메서드의 이름에 Result을 추가하는 래퍼 컨테이너 이름을 강제로 중지 할 수있었습니다. 트릭은 웹 서비스 인터페이스에 다음과 같은 장식의 속성을 추가했다 :

[return:MessageParameter(Name = "whatIWantItNamed")] 

이 속성은 인터페이스에서 직접 [OperationContract] 속성 후 (그냥 실제 방법 스텁 전)에 위치/배치해야합니다.

은 (나는 또한 ServiceContractOperationContract의 모든 속성에 XmlSerializerFormat 속성을 추가 할 필요가 있었다.)

관련 문제