微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ATLServer WebService 如何返回任意内容的 SOAP 消息给客户 —— 改写atlsoap.h

ATLServer WebService 如何返回任意内容的 SOAP 消息给客户

cheungmine@gmail.com

2007-3-24

      (上篇文章存在问题,这里是可用的版本。)

如果想在下面的WebService方法中返回任意SOAP错误消息给客户,应该这样做:

// 宏定义,错误信息只支持英文半角
#define SOAP_FAULT(errCode,wszDetail)    m_fault.m_soapErrCode = errCode;  m_fault.m_strDetail = wszDetail

     [ soap_method ]
     HRESULT HelloWorld(/*[in]*/ BSTR bstrInput,/*[out,retval]*/ BSTR *bstrOutput)
     {
         CComBSTR bstrOut(L"Hello ");
         bstrOut += bstrInput;
         *bstrOutput = bstrOut.Detach();
        
         SOAP_FAULT(SOAP_E_SERVER,  L"Do you love me,my girl");
         return E_FAIL;
    }
然而,m_fault参数未定义,我们需要把它加入到atlsoap.h文件中。打开atlsoap.h,加入下面的代码,注意红色部分是我加的,其他地方不要改变:
template  < typename THandler >
class  CSoapHandler : 
    
public  CSoapRootHandler, 
    
public  CComObjectRootEx < CComMultiThreadModel > ,
    
public  IRequestHandlerImpl < THandler >
{
protected :
    HTTP_CODE    m_hcErr;
    CHttpResponse 
* m_pHttpResponse;

    
//  heap for SOAP requests
    CWin32Heap    m_heap;

    
//  default heap is COM heap (SOAP Servers can double as COM objects)
    CComHeap    m_comHeap;

    
// CL2: 这里添加成员用来返回用户定制的错误,而不是根据HRESULT值生成错误
    CSoapFault  m_fault;
public :

    BEGIN_COM_MAP(CSoapHandler
< THandler > )
        COM_INTERFACE_ENTRY(ISAXContentHandler)
        COM_INTERFACE_ENTRY(IRequestHandler)
    END_COM_MAP()

    CSoapHandler()
        :m_pHttpResponse(NULL), m_hcErr(HTTP_SUCCESS)
    {
        SetMemmgr(
& m_comHeap);
    }

    
void  SetHttpError(HTTP_CODE hcErr)
    {
        m_hcErr 
=  hcErr;
    }

    HRESULT SoapFault(
        SOAP_ERROR_CODE errCode, 
        
const  wchar_t  * wszDetail,
        
int  cchDetail)
    {
        ATLASSUME( m_pHttpResponse 
!=  NULL );

        SetHttpError(AtlsHttpError(
500 , SUBERR_NO_PROCESS));

        m_pHttpResponse
-> ClearHeaders();
        m_pHttpResponse
-> ClearContent();
        m_pHttpResponse
-> SetContentType( " text/xml " );
        m_pHttpResponse
-> SetStatusCode( 500 );
        
        
if (m_fault.m_soapErrCode ==  SOAP_E_UNK)
        {
            
if  (wszDetail  !=  NULL)
            {
                
if  (cchDetail  <   0 )
                {
                    cchDetail 
=  ( int ) wcslen(wszDetail);
                }

                _ATLTRY
                {
                    m_fault.m_strDetail.SetString(wszDetail, cchDetail);
                }
                _ATLCATCHALL()
                {
                    ATLTRACE( _T(
" CSoapHandler::SoapFault -- out of memory. "  ) );

                    
return  E_OUTOFMEMORY;
                }
            }

            m_fault.m_soapErrCode 
=  errCode;
        }

        m_fault.GenerateFault(m_pHttpResponse);

        
return  S_OK;
    }
    ... ...
以上就这些就可以了,运行就看到返回的错误信息“<Detail>Do you love me,my girl</Detail>”。
我使用VS2005+ATL8来写WebService。用其他语言写的WebService不知道存在这些问题不。如果要用好ATL Server,对它的代码做些修改是很正常的。我修改了它很多认的实现,比如CSessionStateService、CPerfMon等类。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐