Send E-mail from javascript using web service - XMLHTTP (in JSON)
רציתי להראות שימוש נחמד בדבר הזה.
אפשר להוריד את הפרויקט -
מכאן.
סיפור לקוח:
הוא מוציא עבודה לגרפיקאים שמחזירים לו דפי html ו - css שהוא משלב באתר שלו - באותם טפסים יש הרבה פעמים שליחה של מיילים - הוא לא רוצה לקחת את מה שהוא מקבל מהגרפיקאים ולהמיר את זה ל - asp.net, הוא רוצה להשתמש בהם כמו שהוא קיבל - והכי הרבה הוא מוכן לכתוב פונקציית JS שתאסוף את הנתונים מהדף ותשלח אותם במייל, איך עושים את זה ?
שלב ראשון נגדיר פרויקט מסוג WebService נקרא לו MailWebServices, בתוכו נגדיר מחלקה בשם MailData (שהלקוח ישלח מופע שלה לשרת)
public class MailData
{
public string From { get; set; }
public string[] To { get; set; }
public string[] CC { get; set; }
public string[] BCC { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public bool IsBodyHtml { get; set; }
}
נגדיר WebService בשם MailService עם מתודה אחת שנקראת SendMail
לא לשכוח להוריד את ההערה על ScriptService (על המחלקה) - אחרת לא יוכלו להפעיל את המתודות מ - JS.
[WebMethod]
public string SendMail(MailData mailData)
{
try
{
MailMessage mail = GetMailMessage(mailData);
SmtpClient client = new SmtpClient();
client.Send(mail);
return true.ToString();
}
catch (Exception ex)
{
return ex.ToString();
}
}
אנחנו מקבלים מופע של MailData, ממירים את זה ל - MailMessage (מיד נראה את הפונקצייה) מייצרים אובייקט מסוג SmtpClient ושולחים את ההודעה.
בנקודה הזאת אנחנו צריכים להגדיר כמה הגדרות בקונפיג.
1. תחת system.web צריך להוסיף:
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
אחרת לא נוכל להפעיל את ה - webService רק ב - SOAP.
2. צריך להגדיר את ה - SmtpClient (תחת configuration)
<system.net>
<mailSettings>
<smtp>
<network host="127.0.0.1" port="25"/>
</smtp>
</mailSettings>
</system.net>
כמובן שה - IP צריך להשתנות לפי הדומיין שלכם (כרגע זה מוגדר localhost).
בצד השרת נשאר לנו רק להסתכל על המתודה GetMailMessage
private static MailMessage GetMailMessage(MailData mailData)
{
MailMessage mail = new MailMessage();
if (mailData.BCC != null)
{
foreach (var item in mailData.BCC)
{
mail.Bcc.Add(item);
}
}
mail.Body = GlobalObject.unescape(mail.Body);
if (mailData.CC != null)
{
foreach (var item in mailData.CC)
{
mail.CC.Add(item);
}
}
mail.From = new MailAddress(mailData.From);
mail.Subject = GlobalObject.unescape(mailData.Subject);
foreach (var item in mailData.To)
{
mail.To.Add(item);
}
mail.IsBodyHtml = mailData.IsBodyHtml;
return mail;
}
קוד די פשוט - יוצרים אובייקט מסוג MailMessage ומכניסים לתוכו את כל הערכים מתוך mailData.
הדבר היחיד המעניין הוא המתודה unescape של GlobalObject - זה מתודה שיודעת להמיר תווים ששנשלחו ב - ASCII לעברית וכו' - (צריך להוסיף reference ל - Microsoft.JScript).
עד כאן ראינו הגדרה של WebService שיודע לשלוח מיילים, כעת נראה איך אפשר לפנות אליו מצד הלקוח.
נגדיר שני קבצי JS - הראשון נקרא לו JSONResponse.js שבו יהיה לנו קוד פשוט ליצירת ה - XMLHttp ועבודה איתו (כמובן שאפשר לעבוד עם ספריות של ajax או jquery, אבל רציתי לשמור על פשטות וקוד קטן)
הנה הקוד שלו:
var isIE = navigator.appName.indexOf('icros') > -1;
function GetSynchronousJSONResponse(url, postData) {
if (isIE) {
return IEXmlHttp(url, postData);
}
else {
return FFXmlHttp(url, postData);
}
}
function IEXmlHttp(url, postData) {
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST", url, false); //false means synchronous
xmlhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xmlhttp.send(postData);
var responseText = xmlhttp.responseText;
return responseText;
}
function FFXmlHttp(url, postData) {
var xmlHttpFF = new XMLHttpRequest();
xmlHttpFF.open("POST", url, false);
xmlHttpFF.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xmlHttpFF.send(postData);
var responseText = xmlHttpFF.responseText;
return responseText;
}
הפונקצייה החשובה כאן היא GetSynchronousJSONResponse שמקבלת את הכתובת של ה - service ומה לשלוח כפרמטר, בנוסף זה יודע לייצר את האובייקט המתאים לפי הדפדפן.
בנוסף יש לי קובץ js שנקרא PostData.js שבו יש הגדרה של המלחקה MailData ב - JS וכן הפונקציות להמרה של מופע מהמחלקה לפורמט JSON.
בהתחלה יש את ההגדרה הבאה:
var MailData = new Object();
MailData.From = '';
MailData.Subject = '';
MailData.Body = '';
MailData.IsBodyHtml = false;
MailData.To = new Array();
MailData.CC = new Array();
MailData.BCC = new Array();
למעשה הגדרנו אובייקט חדש ב - JS שיש לו את כל המאפיינים הכתובים (מוגדר אחד לאחד כמו האוביירט בצד השרת)
בנוסף יש לנו פונקצייה שנקראת SendMail שמקבלת מופע שלו
function SendMail(postData) {
var to = JsonStringForArray(postData.To);
var cc = JsonStringForArray(postData.CC);
var bcc = JsonStringForArray(postData.BCC);
var jsonPostData = '{mailData: { Url: "' + postData.Url +
'", From: "' + postData.From +
'", Subject: "' + postData.Subject +
'", Body: "' + postData.Body +
'", To: ' + to +
', CC: ' + cc +
', BCC: ' + bcc +
', IsBodyHtml: ' + postData.IsBodyHtml +
' }}';
return GetSynchronousJSONResponse("http://localhost:51202/MailService.asmx/SendMail", jsonPostData);
}
הפונקצייה מקבלת מופע של MailData ומייצרת מחרוזת בפורמט JSON -
בנוסף יש לי מערכים (To, CC, BCC) שצריך להמיר אותם ל - JSON, יש את הפונקציה
function JsonStringForArray(arr) {
var obj = '[';
for (var i = 0; i < arr.length; i++) {
obj += '"' + arr[i] + '",';
}
if (obj == '[') {
obj = null;
}
else {
obj = obj.substr(0, obj.length - 1);
obj += ']';
}
return obj;
}
שמקבלת מערך של מחרוזת - ומחיזרה אותו ב - JSON.
בסוף הפונקצייה אנחנו קוראים ל -
GetSynchronousJSONResponse והמייל אמור להשלח.
לדוגמא - הקוד ב - html
<input type="button" onclick="send()" value="send" />
<script src="JSONResponse.js" type="text/javascript"></script>
<script src="PostData.js" type="text/javascript"></script>
<script type="text/javascript">
function send() {
var postData = MailData;
postData.From = 'a@a.co.il';
postData.To[0] = 'xxx@gmail.co.il';
postData.To[1] = 'zzzz@walla.co.il';
postData.CC[0] = 'aaa@gmail.com';
postData.BCC[0] = 'mywork@gmail.com';
postData.Subject = 'this is a subject';
postData.Body = 'this is a body 123';
postData.IsBodyHtml = false;
var res = SendMail(postData);
alert(res);
}
</script>
כעת אותו לקוח מקבל דפי ה - html מהגרפיקאים.
נותן אותם למתכנת שלו ומה שהוא צריך לעשות זה:
להוסיף referenct לאותם שני קבצי JS ולכתוב פונקציית JS שתאסוף את הנתונים מהדף ולקרוא למתודה SendMail.
בהצלחה