代码之家  ›  专栏  ›  技术社区  ›  AboutDev

用于SMS的.NET代码

  •  7
  • AboutDev  · 技术社区  · 16 年前

    我正在编写一些代码,通过Zeep Mobile发送/接收短信( http://zeepmobile.com/developers/

    我查看了他们的谷歌群组,甚至联系了他们的支持人员,但他们并不善于回馈,我现在真的是瞎了眼。

    我必须与它们集成(工作需要它),我不知道为什么我的代码不能工作。因此,我想知道是否有人有任何C#.Net代码,他们不介意共享,以便我可以将其集成到我的应用程序中。

    当然,这完全取决于您是否有使用Zeep的经验。如果你想让我发布代码,我也可以。让我知道。

    谢谢你,我真的很感谢你的帮助。

    **

    编辑:我已经在这里添加了源代码,以防任何人都能提供帮助!

    **

    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Net.Security;
    using System.Web;
    using System.Web.Handlers;
    using System.IO;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    
    
    namespace ConsoleApplication1
    {
    
    
        class Program
        {
            public static string API_KEY = "MY_API_KEY";
            public static string SECRET_ACCESS_KEY = "MY_SECRET_KEY";
            public static string PATTERN_RFC1123 = "ddd, dd MMM yyyy HH:mm:ss " + "GMT";
    
            static void Main(string[] args)
            {
                // URL for sending message - 
                //      send_message = "https://api.zeepmobile.com/messaging/2008-07-14/send_message";
                //      blast_message = "https://api.zeepmobile.com/messaging/2008-07-14/blast_message";
                string apiurl = "https://api.zeepmobile.com/messaging/2008-07-14/blast_message";
    
    
                // FORMAT must be Sun, 06 Nov 1994 08:49:37 GMT
                string http_date = DateTime.UtcNow.ToString("r");
                // Text to send
                string body = HttpUtility.UrlEncode("Test message.", System.Text.Encoding.UTF8);
                // NOTE: Use 'user_id=22&body=' instead of just 'body=' when sending a message to a user.
                // 22 is a user I have previously registered with ZEEP and is used for testing purposes.
                string parameters = "body=" + body; 
                // String that will be converted into a signature.
                string canonicalString = API_KEY + http_date + parameters;
    
    
                //------------START HASH COMPUTATION---------------------
                // Compute the Base64 HMACSHA1 value
                HMACSHA1 hmacsha1 = new HMACSHA1(SECRET_ACCESS_KEY.ToByteArray());
    
                // Compute the hash of the input file.
                byte[] hashValue = hmacsha1.ComputeHash(canonicalString.ToByteArray());
    
                String b64Mac = hashValue.ToBase64String();
                String authentication = String.Format("Zeep {0}:{1}", API_KEY, b64Mac);
                //-----------END HASH COMPUTATION------------------------
    
    
                // We are using TCPClient instead of an HTTPWebRequest because we need to manually
                // set the "Headers" such as Date, Authorization etc which cannot easily be done with HTTPWebRequest.
                Uri reqUrl = new Uri(apiurl);
                TcpClient client = new TcpClient(reqUrl.Host, reqUrl.Port);
                NetworkStream netStream = client.GetStream();
                // SSLStream is used for secure communication. ZEEP requires the use of SSL to send and SMS.
                System.Net.Security.SslStream sslStream = new System.Net.Security.SslStream(
                    netStream, 
                    false, 
                    new System.Net.Security.RemoteCertificateValidationCallback(ValidateServerCertificate));
                sslStream.AuthenticateAsClient(reqUrl.Host);
    
    
                // POST content we are going to transmit over the SSL channel. 
                // See. http://zeepmobile.com/developers/documentation/messaging/2008-07-14/rest_api#send_message
                System.IO.StreamWriter s = new System.IO.StreamWriter(sslStream);
                s.WriteLine(String.Format("POST {0} HTTP/1.1", "/api/blast"));
                s.WriteLine(String.Format("Host: {0}", "api.zeepmobile.com"));
                s.WriteLine(String.Format("Authorization: Zeep {0}:{1}", API_KEY, b64Mac));
                s.WriteLine(String.Format("Date: {0}", http_date));
                s.WriteLine(String.Format("Content-Type: {0}", "application/x-www-form-urlencoded"));
                s.WriteLine(String.Format("Content-Length: {0}", parameters.Length));
                s.WriteLine(String.Format("{0}", parameters));
                s.Flush();
    
    
                System.IO.StreamReader r = new StreamReader(sslStream);
                string resp = r.ReadToEnd();
                Console.WriteLine(resp);
                r.Close();
    
            }
    
            // The following method is invoked by the RemoteCertificateValidationDelegate.
            // We want to make sure the SSL has no Policy errors and is safe.
            public static bool ValidateServerCertificate(
                  object sender,
                  X509Certificate certificate,
                  X509Chain chain,
                  SslPolicyErrors sslPolicyErrors)
            {
                if (sslPolicyErrors == SslPolicyErrors.None)
                    return true;
    
                Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
    
                // Do not allow this client to communicate with unauthenticated servers.
                return false;
            }
    
        }
    
        public static class Extensions
        {
            public static byte[] ToByteArray(this string input)
            {
                UTF8Encoding encoding = new UTF8Encoding();
                return encoding.GetBytes(input);
            }
    
            public static string ToBase64String(this byte[] input)
            {
                return Convert.ToBase64String(input);
            }
        }
    }
    

    错误

    运行此代码时发生的错误如下图所示。

    alt text

    2 回复  |  直到 8 年前
        1
  •  5
  •   AboutDev    16 年前

    解决方案:

    好啊昨天晚上我一直在努力,取得了一些进展。我使用Fiddler来构造POST消息,以查看上面的内容与服务器期望的内容之间的任何差异。

    我让它发送消息并返回HTTP 200 OK响应。同样,这段代码还没有准备好生产,只是需要测试一下,看看是否可以让Zeep正常工作。感谢所有回复的人,如果您正在寻找ZEEP代码,我希望这能对您有所帮助。


    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Net.Security;
    using System.Web;
    using System.Web.Handlers;
    using System.IO;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    
    
    namespace ConsoleApplication1
    {
        class Program
        {
            public static string API_KEY = "YOUR_API_KEY_GOES_HERE! INCLUDE DASHES!";
            public static string SECRET_ACCESS_KEY = "YOUR_SECRET_KEY_GOES_HERE!";
    
            static void Main(string[] args)
            {
                Console.WriteLine("BLAST - \r\n\r\n");
                BlastTcpPost();
    
                Console.WriteLine("SEND - \r\n\r\n");
                SendTcpPost();
            }
    
            /// <summary>
            /// Send a BLAST to all users in your ZEEP account.
            /// </summary>
            public static void BlastTcpPost()
            {
                SendSMS(
                    "https://api.zeepmobile.com/messaging/2008-07-14/blast_message",    // URL for Send_Message 
                    "You are on blast",                                                 // Message to send
                    string.Empty                                                        // No UserId to send.
                    );
            }
    
            /// <summary>
            /// Send a single message to a user in your ZEEP account.
            /// </summary>
            public static void SendTcpPost()
            {
                // Note:- 22 I use for the UserId is just a user I have signed up. Yours may be different and you 
                // might want to pass that in as a parameter.
    
                SendSMS(
                    "https://api.zeepmobile.com/messaging/2008-07-14/send_message",     // URL for Send_Message
                    "You are a user...good job!",                                       // Message to send
                    "22"                                                                // User Id in your system.
                    );
    
            }
    
            /// <summary>
            /// Uses a TCPClient and SSLStream to perform a POST.
            /// </summary>
            /// <param name="requestUrl">URL that the POST must be directed to.</param>
            /// <param name="body">Message that is to be sent.</param>
            /// <param name="user">UserId in your Zeep System. Only required if your sending a Single Message to a User. 
            /// Otherwise, just send a string.Empty.</param>
            /// <returns>Response from the server. (although it will write the response to console)</returns>
            public static string SendSMS(string requestUrl, string body, string user)
            {
                string parameters = "";
                string requestHeaders = "";
                string responseData = "";
    
                // FORMAT must be Sun, 06 Nov 1994 08:49:37 GMT
                string http_date = DateTime.UtcNow.ToString("r");
    
                // Clean the text to send
                body = HttpUtility.UrlEncode(body, System.Text.Encoding.UTF8);
    
                if (user.Length > 0) parameters += "user_id=" + user + "&";
                if (body.Length > 0) parameters += "body=" + body;
    
    
                // String that will be converted into a signature.
                string canonicalString = API_KEY + http_date + parameters;
    
    
                //------------START HASH COMPUTATION---------------------
                // Compute the Base64 HMACSHA1 value
                HMACSHA1 hmacsha1 = new HMACSHA1(SECRET_ACCESS_KEY.ToByteArray());
    
                // Compute the hash of the input file.
                byte[] hashValue = hmacsha1.ComputeHash(canonicalString.ToByteArray());
    
                String b64Mac = hashValue.ToBase64String();
                String authentication = String.Format("Zeep {0}:{1}", API_KEY, b64Mac);
                //-----------END HASH COMPUTATION------------------------
    
    
                string auth = String.Format("Zeep {0}:{1}", API_KEY, b64Mac);
    
    
                System.Uri uri = new Uri(requestUrl);
                System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient(uri.Host, uri.Port);
                string requestMethod = "POST " + uri.LocalPath + " HTTP/1.1\r\n";
    
                // Set Headers for the POST message
                requestHeaders += "Host: api.zeepmobile.com\r\n";
                requestHeaders += "Authorization: " + auth + "\r\n";
                requestHeaders += "Date: " + DateTime.UtcNow.ToString("r") + "\r\n";
                requestHeaders += "Content-Type: application/x-www-form-urlencoded\r\n";
                requestHeaders += "Content-Length: " + parameters.ToByteArray().Length + "\r\n";
                requestHeaders += "\r\n";
    
    
                // Get the data to be sent as a byte array.
                Byte[] data = System.Text.Encoding.UTF8.GetBytes(requestMethod + requestHeaders + parameters + "\r\n");
                // Send the message to the connected TcpServer.
                NetworkStream stream = client.GetStream();
    
    
                // SSL Authentication is used because the Server requires https.
                System.Net.Security.SslStream sslStream = new System.Net.Security.SslStream(
                    stream,
                    false,
                    new System.Net.Security.RemoteCertificateValidationCallback(ValidateServerCertificate));
                sslStream.AuthenticateAsClient(uri.Host);
    
                // Send the data over the SSL stream.
                sslStream.Write(data, 0, data.Length);
                sslStream.Flush();
    
    
                // Receive the TcpServer.response.
                for (int i = 0; i < 100; i++)
                {
                    if (stream.DataAvailable)
                    {
                        break;
                    }
                    System.Threading.Thread.Sleep(100);
                }
    
                Byte[] bytes = new byte[1024];
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                while (stream.DataAvailable)
                {
                    int count = sslStream.Read(bytes, 0, 1024);
                    if (count == 0)
                    {
                        break;
                    }
                    sb.Append(System.Text.Encoding.UTF8.GetString(bytes, 0, count));
                }
    
                responseData = sb.ToString();
                Console.WriteLine(responseData);
                // Close everything.
                client.Close();
    
                return responseData;
            }
    
    
    
            // The following method is invoked by the RemoteCertificateValidationDelegate.
            // We want to make sure the SSL has no Policy errors and is safe.
            public static bool ValidateServerCertificate(
                  object sender,
                  X509Certificate certificate,
                  X509Chain chain,
                  SslPolicyErrors sslPolicyErrors)
            {
                // Somehow the cert always has PolicyErrors so I am returning true regardless.
                return true;
                //if (sslPolicyErrors == SslPolicyErrors.None)
                //    return true;
    
                //Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
    
                //// Do not allow this client to communicate with unauthenticated servers.
                //return false;
            }
        }
    
        public static class Extensions
        {
            public static byte[] ToByteArray(this string input)
            {
                UTF8Encoding encoding = new UTF8Encoding();
                return encoding.GetBytes(input);
            }
    
            public static string ToBase64String(this byte[] input)
            {
                return Convert.ToBase64String(input);
            }
        }
    }
    
        2
  •  2
  •   peSHIr    16 年前

    TcpClient SslStream 和泽普交流?我会试着用一个 HttpWebRequest

    我不必 如果我使用正确的.NET框架 WebRequest