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;
        }
    }

} 

 

 

posted on 2011-09-01 13:53  观摩  阅读(1699)  评论(9编辑  收藏  举报