Microsoft MVP성태의 닷넷 이야기
웹서비스 WSDL 생성및 프록시 클래스 생성 관련 질문입니다. [링크 복사], [링크+제목 복사]
조회: 12305
글쓴 사람
초이
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

안녕하세요 닷넷을 하면서 홈페이지 많이참고 하고 있습니다. ^^
감사합니다.

질문에 예제도 아직 작업중인 부분이라 정리가 좀 안되고 긴점 양해 부탁드립니다.
현재 웹서비스 (asmx) 기반으로 메세지 암호화 를 구현하였는데요.
아주 예전에 올려놓으신

https://www.sysnet.pe.kr/2/0/453
서버측 SoapExtension을 클라이언트에 알리고 싶다.

를 참고하여 제가 구현한 SoapExtension 클래스에서 사용하는 내용을 클라이언트 프록시 클래스에서도 나타내게끔 하려고합니다. (SoapExtensionImporter 활용 )
일단 웹서비스의 Input output 은 암호화된 스트링이 넘어 오므로, 해당 스트링의 암호화 / 복호화를 거쳐 ParamEncryptionExtension 에서 처리는 완료 하였습니다.
샘플 웹서비스 메소드는 다음과 같구요.

  [SoapHeader("myEncryptHeader", Direction = SoapHeaderDirection.In)]
  [ParamEncryptionExtension(EncryptParamNames = new string[] { "Test_Output" },
                       LogRequestResponse = true,
                       SerializeType = typeof(Protocol.Test_Output))]

 public XmlNode TestEncrypt(XmlNode input)
 {

input 에는 복호화된 xml 스트링이 넘어오고 ( 클라이언트는 암호화된 스트링을 보냄 ( 원본은 xml string ) )
해당 xml 스트링을 deserilaize 해서 구조체를 만들어 사용합니다.
마찬가지로 웹메소드 안에서 결과값인 특정 구조체를 serialize 해서 xmlnode 로 넘기면 ParamEncryptionExtension 에서 암호화 하여 스트링을 클라이언트 한테 넘겨주고요.

문제는 wsdl.exe 툴 로 생성된 프록시 클래스에서 해당 함수가 XmlNode 지만 어떤 xml type 으로 보내라.. 혹은 어떤 xml type 이 리턴된다 라는걸 알려주고싶은데,
웹서비스 wsdl 문서에서는 다음과 같이 any 타입으로만 표시가 되니 ( 당연한거지만요.. )
클라이언트는 수동으로 xml 을 만들어 보내줘야 하는 상황입니다.

<wsdl:types>
- <s:schema elementFormDefault="qualified" targetNamespace="http://localhost/">
- <s:element name="TestEncrypt">
- <s:complexType>
- <s:sequence>
- <s:element minOccurs="0" maxOccurs="1" name="input">
- <s:complexType mixed="true">
- <s:sequence>
  <s:any />
  </s:sequence>
  </s:complexType>
  </s:element>
  </s:sequence>
  </s:complexType>
  </s:element>

wsdl 파일 에 특정 구조체를 포함시켜주기 위해 (여기서는 TestEncrypt 메소드의 output 형식 )
다음과 같이 클래스를 선언하고,

    [XmlRootAttribute]
    public class TestOutput
    {
        [XmlElement]
        public string o_session_id;
        [XmlElement]
        public int nResult;
    }

SoapExtensionReflector 에서 다음과 같이 작성해주었더니,
 
      XmlTypeMapping mapping = ReflectionContext.ReflectionImporter.ImportTypeMapping(typeof(TestOutput));
      ReflectionContext.SchemaExporter.ExportTypeMapping(mapping);
           
      ParamEncryptionExtensionAttribute attr = (ParamEncryptionExtensionAttribute)attrs[0];

      ParamEncryptionOperationBinding operationBinding = new ParamEncryptionOperationBinding();
      operationBinding.SerializeType = attr.SerializeType.Name;
      operationBinding.Output = true;
 
      ReflectionContext.OperationBinding.Extensions.Add(operationBinding);

wsdl 파일의 types 에 제가 노출시키려던 Test_Output 이 다음과 같이 표시 되주고요,
전에 강좌에서 올려놓으셨던, operation 섹션에 OperationBinding 도 표시가 잘 됩니다.

<wsdl:types>
- <s:schema elementFormDefault="qualified" targetNamespace="http://localhost/">
   ... 생략 ...
- <s:complexType name="TestOutput">
- <s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="o_session_id" type="s:string" />
  <s:element minOccurs="1" maxOccurs="1" name="nResult" type="s:int" />
  </s:sequence>
  </s:complexType>
  </s:schema>
   ... 생략 ....
 </wsdl:types>


- <wsdl:operation name="TestEncrypt">
  <soap12:operation soapAction="http://localhost/TestEncrypt" style="document" />
  <enc:encryption Input="true" Output="true" SerializeType="Test_Output" />
- <wsdl:input>
  <soap12:body use="literal" />
  <soap12:header message="tns:TestEncryptTestSoapHeader" part="TestSoapHeader" use="literal" />
  </wsdl:input>
- <wsdl:output>
  <soap12:body use="literal" />
  </wsdl:output>
  </wsdl:operation>

하지만 이부분도 wsdl.exe 로 프록시 클래스를 생성하면

/// <remarks/>
// CODEGEN: 네임스페이스 'http://localhost"에서 선택적 WSDL 확장 요소 'encryption'이(가) 처리되지 않았습니다.
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]

SoapExtensionImporter 구현 및 Web.config 에 해당 클래스들은 다 포함하여주었습니다만
위와 같이 warning 만해주고 어트리뷰트는 코드에 생성되지 않구요.
물론 위에서 wsdl types 에 추가되었던 Test_Output 구조체도 프록시 클래스에선 찾아볼수 없습니다.
SoapExtensionImporter 구현은 msdn 을 참고 하여 다음과 같이 구현하였습니다.

public class EncryptionExtensionImporter : SoapExtensionImporter
    {
        public override void ImportMethod(CodeAttributeDeclarationCollection metadata)
        {
            ParamEncryptionOperationBinding myOpBinding = (ParamEncryptionOperationBinding)
                ImportContext.OperationBinding.Extensions.Find(typeof(ParamEncryptionOperationBinding));
            if (myOpBinding != null)
            {
                    CodeAttributeDeclaration attr = new CodeAttributeDeclaration( typeof(ParamEncryptionExtensionAttribute).FullName);
                    attr.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(true)));
                    metadata.Add(attr);
            }
        }


결론적으로 제가 하고 싶은건 웹메소드의 Input Ouput 이 비록 XmlNode 타입이지만 클라이언트에서
해당 웹메소드의 Input Output 각각 XmlNode 에 어떤 구조체가 serialze 혹은 deserialze 된다 라는것을 알려줌과 동시에
해당 구조체도 wsdl.exe 에 의해서 프록시 클래스에 자동적으로 생생되게 하고 싶습니다.

그렇게 처리할수 있는 방법이 있을까요?
긴글 읽어주셔서 감사드리며 고견 부탁드립니다.


[연관 글]






[최초 등록일: ]
[최종 수정일: 1/4/2014]


비밀번호

댓글 작성자
 



2014-01-07 01시53분
저도 기억이 이젠 가물가물하군요. ^^; 하도 오래 전에 쓴 내용이라서. 일단 보면 서버 측에서는 WSDL에 직렬화 정보를 잘 포함시킨 것 같습니다. 보여주신 내용대로 enc:encryption 노드로 포함이 되었으니 남은 것은 클라이언트 측의 처리인데요. SoapExtensionImporter를 만드셨다고 했는데, 동작이 정상적으로 되는 것을 확인하셨나요? 그 부분이 정상적으로 동작하고 있다면 코드 생성 시에 WSDL의 내용을 읽어서 코드 생성에 참여할 수 있을 텐데요. 질문해 주신 내용은 클라이언트 측 WSDL 소스 코드 생성에 참여하는 것이 제대로 동작하는지만 테스트 해보면, 그 이후는 적절하게 코드 생성을 하면 되니까 보완하기 나름일 것 같습니다.
정성태

... 16  17  18  19  20  21  22  23  24  25  26  27  28  [29]  30  ...
NoWriterDateCnt.TitleFile(s)
5155세퉁5/7/201910361관리자 권한으로 실행 시 알림창(?) 없이 바로 실행 시킬 수 있는 방법이 있을까요?? [2]파일 다운로드1
5154Soul...5/4/20197241NamedPipe 질문드립니다. [2]
5153개태5/4/20198199WCF RESTful Service에서 enum을 parameter로 쓰는방법 [2]
5152세퉁5/3/20199329인터넷 시간을 불러와 pc에 적용 시키고 싶습니다. [3]파일 다운로드1
5151이대희5/3/20197431C# 7.3으로 개정판 출간 계획이 있으신가요? [1]
5150김이현5/2/20198805C# 딕셔너리 생성에 대해 질문드립니다. [1]
5149민성5/1/20197060ftp 이미지 업로드중 [1]
5148wpf질문4/30/20197419특정 사이트를 wpf에서 popup을 항상 허용하게 할려면 어떻게 해야할까요? [5]
5147민성4/30/20196438wpf에서 작업관리자를 띠울려면 어떻게 해야 하나요? [1]
5146불파겐4/25/20196495하나의 필드를 여러 스레드에서 읽어갈 때 스레드 동기화를 하지 않으면 문제가 생길까요? [2]
5145e구름4/17/20199473Properties.Setting.Default값에 대해 질문드립니다. [2]
5144성태님 ...4/17/20196665질문하시기 전에 10000 페이지 오류 납니다. [1]
5143헌이4/16/20197586윈도우 작업표시줄에 프로그램 띄우기 [2]파일 다운로드1
5142cab2...4/9/201913178C#으로 만든 DLL 배포하기 [10]
5141하늘사랑4/5/20198058Axinterop 래퍼에 관해서 질문드립니다. [7]
5140게스트4/1/20197694안녕하세요. 초보 개발자입니다. SD리더기에서 SD카드를 꽂으면 발생하는 이벤트 문의 [2]
5139김이현3/28/201910906C#에서 CRON 같은 스케줄러를 사용하려면 어떻게 해야 하나요? [3]
5138김지원3/22/20198539유니티 쉐이더에서 오로지 포워드 애드 패스로만 만들 수 있을까요? [1]
5137세퉁3/22/201910478wpf 쓰레드에 대해 질문 있습니다. [4]
5136KGY3/13/20197168안녕하세요 닷넷코어 콘솔 프로그램 관련 질문입니다. [1]
5135러쎌3/13/20197596ASP.NET 공부 관련해서 문의를 드립니다. [1]
5134이정호3/12/20196996SampleProfiler 예제를 이용한 Class 객체의 접근 문의 [1]파일 다운로드1
5133ㅇㅇ3/12/20197880멀티코어사용 방법에 궁금한것이 있습니다. [3]
5132존기미3/3/20198117Physical Disk Access문의 [1]
5131강용규2/25/20197226c# 개발자입니다. 타이머 질문드립니다. [1]
5130노인코래방2/25/201910756C#에서 가장 좋은 성능을 보이는 파일 읽고 쓰는 방법이 무엇인가요? [2]
... 16  17  18  19  20  21  22  23  24  25  26  27  28  [29]  30  ...