我对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.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;
}
然后
找到你要调用的那个服务方法,在上面添加 [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.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.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;
}
}
}