نوشته شده توسط
aidin2345
با سلام
دوستان یه کمک میخواستم در مورد اینکه از یه وب سرویس ارسال پیامک که لیست پیامهایی که به شماره اختصاصی فرستاده شدن رو توی گرید ویووو بتونم نمایش بدم و در نهایت تاریخی که در Result داده رو تبدیل کنه به تاریخ دریافت پیام
دو تا کار باید انجام بشه، اولی ارسال درخواست و دریافت پاسخ ئه و دومی تفسیر JSON پاسخ.
برای اینکه DataContractJsonSerializer بتونه JSON رو بخونه کلاس های مرتبط رو تعریف می کنیم :
کلاس اصلی که JSON میخونه :
[DataContract]
private class PageData
{
[DataMember]
public int Code { get; set; }
[DataMember]
public string Message { get; set; }
[DataMember]
public ResultData[] Result { get; set; }
}
و محتویات اون کلاس :
[DataContract]
private class ResultData
{
[DataMember]
public int Page { get; set; }
[DataMember]
public int TotalPage { get; set; }
[DataMember]
public MessageData[] ReceivedMsgs { get; set; }
}
[DataContract]
private class MessageData
{
[DataMember]
public string MsgBody { get; set; }
[DataMember]
public string Mobile { get; set; }
[DataMember]
public long Date { get; set; }
}
و یک کلاس ایجاد می کنیم که همه عملیات رو از داخلش انجام بده :
public class SmsProvider
{
public SmsProvider(string username, string password);
public DataTable GetMessages(string phoneNumber, string url, DateTime startDate, DateTime endDate);
}
در نهایت ابتدا یک شیء از SmsProvider با نام کاربری و رمز عبور مورد نظر ایجاد می کنیم و بعد با GetMessages درون یک جدول DataTable پیام ها رو دریافت می کنیم.
در متد سازنده کلاس authHeader_ رو که در درخواست ها درون Authorization ثبت میشه مقدار دهی می کنیم :
private readonly string _authHeader;
public SmsProvider(string username, string password)
{
var auth = username + ":" + password;
var encodedAuth = Convert.ToBase64String(Encoding.UTF8.GetBytes(auth ));
_authHeader = "Basic " + encodedAuth;
}
و دو تا متد می سازیم که بین DateTime و Timestamp تبدیل داده رو انجام بده :
private static long GetUnixTimestamp(DateTime dateTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
return (long)TimeZoneInfo.ConvertTimeToUtc(dateTime).Subt ract(epoch).TotalSeconds;
}
private static DateTime GetDateTime(long timestamp)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(timestamp);
}
و GetMessage رو طوری کد نویسی می کنیم که اول یک DataTable بسازه، ستون هاش رو ایجاد کنه و صفحه اول رو دریافت کنه و پیام هاش رو در DataTable درج کنه و بعد اگر تعداد کل صفحات بیشتر از 1 بود صفحات بعدی رو هم دریافت کنه. این متد به متد GetPage وابسته است که باید یک صفحه رو دریافت کنه و بعد با متد DecodePage هم JSON رو تفسیر کنه.
public DataTable GetMessages(string phoneNumber, string url, DateTime startDate, DateTime endDate)
{
var dt = new DataTable();
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("Mobile");
dt.Columns.Add("MsgBody");
var bytes = GetPage(phoneNumber, url, startDate, endDate, 1);
var totalPage = DecodePage(bytes, dt);
for (var i = 2; i <= totalPage; i++)
{
bytes = GetPage(phoneNumber, url, startDate, endDate, i);
DecodePage(bytes, dt);
}
return dt;
}
در متد GetPage یک صفحه رو دریافت می کنیم، چیزی که دریافت میشه آرایه ای از بایت ها است که قاعدتا رشته در سیستم UTF8 خواهد بود :
private byte[] GetPage(string phoneNumber, string url, DateTime startDate, DateTime endDate, int page)
{
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.Authorization] = _authHeader;
var values = new NameValueCollection
{
["PhoneNumber"] = phoneNumber,
["StartDate"] = GetUnixTimestamp(startDate).ToString(),
["EndDate"] = GetUnixTimestamp(endDate).ToString(),
["Page"] = page.ToString()
};
return client.UploadValues(url, values);
}
}
برای تفسیر JSON از DecodePage استفاده می کنیم، علاوه بر اضافه کردن پیام ها در جدول dt این متد تعداد کل صفحات رو بر می گردونه :
private static int DecodePage(byte[] bytes, DataTable dt)
{
var serializer = new DataContractJsonSerializer(typeof(PageData));
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var page = (PageData)serializer.ReadObject(stream);
if (page.Code != 0)
{
throw new Exception(page.Message);
}
if ((page.Result == null) || (page.Result.Length == 0))
{
return 0;
}
var result = page.Result[0];
if (result.ReceivedMsgs == null)
{
return result.TotalPage;
}
foreach (var message in result.ReceivedMsgs)
{
var row = dt.NewRow();
row["Date"] = GetDateTime(message.Date);
row["Mobile"] = message.Mobile;
row["MsgBody"] = message.MsgBody;
dt.Rows.Add(row);
}
return result.TotalPage;
}
}
اگر فرض کنیم که یک DataGridView رو روی فرم قرار داده ایم، با همچین کدی می توانیم از کلاس SmsProvider استفاده کنیم که فرضا در طول یک ماه گذشته پیام ها رو دریافت کنه و نمایش بده :
try
{
var url = "https://www.xxxxxxxxx.com/api/smsAPI/ReceiveMessages";
var phoneNumber = "98300085552000111";
var startDate = DateTime.Now.AddMonths(-1);
var endDate = DateTime.Now;
var x = new SmsProvider("username", "password");
var dt = x.GetMessages(phoneNumber, url, startDate, endDate);
dataGridView1.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, ex.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
و کد پروژه :
SmsReader.rar