C#调用ISAG网关下发彩信长征路上的一个小脚印

我对C#不能说精通,只能说会用,所以我的描述可能出现很多不专业的词汇,请指正,但不要笑话

首先我要感谢很多人,那些通过电话的,帮我跟踪数据的,QQ聊过的,让我好好看文档的人,是他们让我不得不放弃等靠要,自己看文档,坚信直接调用WSDL生成WebServcie代理类是可以成功下发彩信的。

但是我更要感谢BaiDu、Google,是他们让我找到之路的明灯

我还要感谢ethereal这个工具,有了他我才能更方便的看到自己发送的数据包,接收到的数据包都是什么内容

我还要感谢PortMap这个工具,因为ISAG网关是认证服务器IP地址的,而我总不能一直在服务器上调试吧,用他在服务器上做一个端口转发我才能方便的在本地调试

还要感谢csdn,我通过Google找到了

【调用SOAP信息验证的WEBSERVICE的一个问题】http://topic.csdn.net/u/20080916/12/0564F1B2-EABF-4B9F-8E7B-15BB32781D0C.html

进而找到了

【[.NET][C#]dotNet使用WSE3.0调用java的web服务】http://blog.csdn.net/much0726/article/details/2943364


在VS里面添加webService,地址引用ctcc_mm_receive_service_2_2.wsdl

我们可以看到sendMessage,这个类是保存彩信主题,接收方号码,发送方号码的

还有SendMessageService.sendMessage,这个方法是将实例化的sendMessage发送到彩信网关的


如果仅仅这样,我们收到的是报错,通过抓包可以分析到没有SoapHeader,而SP发送彩信是需要SPId等认证信息的,这些信息恰恰就包含在SoapHeader里面,在ctcc_common_types_2_1.xsd里面我们能看到定义的RequestSOAPHeader,可是C#怎么才能调用这个定义好的RequestSOAPHeader呢?

是上面提到的两篇文章帮了我,自己修改VS生成代理类Reference.cs

在最后一个using下面添加下面的内容

    [System.Xml.Serialization.XmlTypeAttribute(Namespace  =   " http://www.chinatelecom.com.cn/schema/ctcc/common/v2_1 " )]
    [System.Xml.Serialization.XmlRootAttribute(Namespace 
=   " http://www.chinatelecom.com.cn/schema/ctcc/common/v2_1 " , IsNullable  =   false )]
    
public   class  RequestSOAPHeader : System.Web.Services.Protocols.SoapHeader
    {
        
public   string  spId  =   "" ;
        
public   string  spPassword  =   "" ;
        
public   string  timeStamp  =   "" ;
        
public   string  productId  =   "" ;
        
public   string  SAN  =   "" ;
        
public   string  transactionId  =   "" ;
        
public   string  transEnd  =   "" ;
        
public   string  linkId  =   "" ;
        
public   string  OA  =   "" ;
        
public   string  FA  =   "" ;
        
public   bool  multicastMessaging  =   false ;

    } 

里面的字段是根据XSD文档定义自己添加的

 

然后

 

找到你要调用的那个服务方法,在上面添加 [System.Web.Services.Protocols.SoapHeaderAttribute("ServiceAuthHeaderValue")]这行代码,注意ServiceAuthHeaderValue是声明的公共成员。 如果你找不到,你可以搜索下类似[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]的代码。对,就在这上面或下面添加。

我添加后的代码为:
        [System.Web.Services.Protocols.SoapHeaderAttribute( " ServiceAuthHeaderValue " )]
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute(
"" , Use  =  System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle  =  System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [
return : System.Xml.Serialization.XmlElementAttribute( " sendMessageResponse " , Namespace  =   " http://www.chinatelecom.com.cn/schema/ctcc/multimedia_messaging/send/v2_2/local " )]
        
public  sendMessageResponse sendMessage([System.Xml.Serialization.XmlElementAttribute( " sendMessage " , Namespace  =   " http://www.chinatelecom.com.cn/schema/ctcc/multimedia_messaging/send/v2_2/local " )] sendMessage sendMessage1)
        {
            
object [] results  =   this .Invoke( " sendMessage " new   object [] {
                        sendMessage1});
            
return  ((sendMessageResponse)(results[ 0 ]));

        } 

 

这样,我们就可以在发送彩信的时候调RequestSOAPHeader,将SoapHeader加入数据包内

 

Form1.cs 

using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Text;
using  System.Windows.Forms;
using  System.Web.Services.Protocols;
using  System.Net;
using  FROM_MMS_DLL.ZTE.MMS;

namespace  FROM_MMS_DLL
{
    
public   partial   class  Form1 : Form
    {
        
public  Form1()
        {
            InitializeComponent();
        }

        
private   void  Form1_Load( object  sender, EventArgs e)
        {

        }

        
private   void  button1_Click( object  sender, EventArgs e)
        {
            SimpleReference receiptRequest 
=   new  SimpleReference();
            receiptRequest.correlator 
=  DateTime.Now.ToString( " yyyyMMddHHmmss " );
            receiptRequest.endpoint 
=   " tel: "   +   13333333333 ;
            receiptRequest.interfaceName 
=   " xxx " ;

            sendMessage mms 
=   new  sendMessage();
            mms.addresses 
=   new   string [] {  " tel: "   +   " 13333333333 "  };
            mms.senderAddress 
=   " 106500000 " ;
            mms.subject 
=   " 中文行不行WSDL_MMS_TEST " ;
            mms.receiptRequest 
=  receiptRequest;

            RequestSOAPHeader soapHeader 
=   new  RequestSOAPHeader();
            soapHeader.spId 
=   " 你的SPID " ;
            soapHeader.timeStamp 
=  DateTime.Now.ToString( " MMddHHmmss " );
            soapHeader.spPassword 
=  GeneratePassword(soapHeader.spId,  " ISAG网关分配的密码 " , soapHeader.timeStamp);
            soapHeader.productId 
=   " 117103089020000000000 " ;
            soapHeader.SAN 
=   " 106500000 " ;
            soapHeader.transactionId 
=   " 0 " ;
            soapHeader.transEnd 
=   " 0 " ;
            soapHeader.linkId 
=   "" ;
            soapHeader.OA 
=   " tel:13333333333 " ;
            soapHeader.FA 
=   "" ;
            soapHeader.multicastMessaging 
=   false ;

            SendMessageService mmsSendService 
=   new  SendMessageService();
            mmsSendService.ServiceAuthHeaderValue 
=  soapHeader;
            mmsSendService.Url 
=  " http://222.222.222.222:2808/MmsSendMessageService ";

            sendMessageResponse sendResponse 
=   new  sendMessageResponse();
            
string  result  =   "" ;
            
try
            {
                sendResponse 
=  mmsSendService.sendMessage(mms);
                result 
=  sendResponse.result;
            }
            
catch  (SoapException ex)
            {
                result 
=  ex.ToString();
            }
            
catch  (Exception ex)
            {
                result 
=  ex.ToString();
            }
            
this .textBox1.Text  =  DateTime.Now  +   "    "   +  result;
        }

        
///   <summary>
        
///  根据SP密码生成提交短信密码
        
///   </summary>
        
///   <param name="spPwd"></param>
        
///   <returns></returns>
         public   string  GeneratePassword( string  spId,  string  spPwd,  string  timeStamp)
        {
            System.Security.Cryptography.MD5 md5 
=   new  System.Security.Cryptography.MD5CryptoServiceProvider();

            
string  spPassword  =  Hex(md5.ComputeHash(Encoding.ASCII.GetBytes(spId  +  spPwd  +  timeStamp)));
            spPassword 
=  spPassword.ToUpper();
            
return  spPassword;
        }

        
///   <summary>
        
///  转换为16进制.
        
///   </summary>
        
///   <param name="s"></param>
        
///   <returns></returns>
         private   static   string  Hex( byte [] s)    //
        {
            
string  ret  =   "" ;
            
for  ( int  i  =   0 ; i  <   16 ; i ++ )
            {
                ret 
+=  s[i].ToString( " x2 " );
            }
            
return  ret;
        }
    }

} 

 

 

你可能感兴趣的:(C#)