venerdì 31 gennaio 2014

C# - How to send an email using the socket

The standard .NET library give you an easy and quick way to send an email in C#. But sometimes you need to set some values in the header and it's not possible to do that using System.Net.Mail.MailMessage. An example is the enveloper from and to set it, the only way, is to set the sender. What if do you need a different sender and envelope from? One way is to send the mail using the socket.

 using System;  
 using System.IO;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Net;  
 using System.Text;  
 using System.Net.Sockets;  
 using Admin.Models;  
 using System.Net.Mail;  
 namespace Admin.Services.Implementation  
 {  
   /// <summary>  
   ///  <para>Wraps an smtp request</para>  
   /// </summary>  
   public class SmtpService : ISmtpService  
   {  
     /// <summary>  
     /// Get / Set the name of the SMTP mail server  
     /// </summary>  
     private enum SMTPResponse : int  
     {  
       CONNECT_SUCCESS = 220,  
       GENERIC_SUCCESS = 250,  
       DATA_SUCCESS = 354,  
       QUIT_SUCCESS = 221  
     }  
     private const int timeOutLimit = 1000;  
     bool ISmtpService.Send(MailMessage message, string SmtpServer, string returnPath)  
     {  
       IPAddress localIPAddress = IPAddress.Parse(SmtpServer);  
       IPEndPoint endPt = new IPEndPoint(localIPAddress, 25);  
       using (Socket s = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp))  
       {  
         //set timeout  
         s.ReceiveTimeout = timeOutLimit;  
         s.SendTimeout = timeOutLimit;  
         // try to establish the connection  
         s.Connect(endPt);  
         if (!Check_Response(s, SMTPResponse.CONNECT_SUCCESS))  
         {  
           s.Close();  
           return false;  
         }  
         // say hello to the server to identify myself  
         SendData(s, string.Format("HELO {0}\r\n", Dns.GetHostName()));  
         if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))  
         {  
           s.Close();  
           return false;  
         }  
         // set the mail from in the envelope  
         SendData(s, string.Format("MAIL From: {0}\r\n", returnPath));  
         if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))  
         {  
           s.Close();  
           return false;  
         }  
         // set the email to in the envelope  
         if (message.To.Count > 0)  
         {  
           foreach (var to in message.To)  
           {  
             SendData(s, string.Format("RCPT TO: {0}\r\n", to.Address));  
             if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))  
             {  
               s.Close();  
               return false;  
             }  
           }  
         }  
         else  
           return false;  
         // add bcc to the envelope  
         if (message.Bcc.Count > 0)  
         {  
           foreach (var to in message.Bcc)  
           {  
             SendData(s, string.Format("RCPT TO: {0}\r\n", to.Address));  
             if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))  
             {  
               s.Close();  
               return false;  
             }  
           }  
         }  
         // create the header as string builder  
         StringBuilder Header = new StringBuilder();  
         Header.Append("MIME-Version: 1.0\r\n");  
         // email priority  
         Header.Append("Importance: " + message.Priority.ToString() + "\r\n");  
         // set the from  
         Header.Append("From: " + message.From.DisplayName + " <" + message.From.Address + ">\r\n");  
         // set the reply to  
         Header.Append("Reply-To: " + message.ReplyToList.FirstOrDefault() + "\r\n");  
         // set the email to  
         Header.Append("To: ");  
         int i = 0;  
         foreach (var To in message.To)  
         {  
           Header.Append(i > 0 ? "," : "");  
           Header.Append(To.Address);  
           i++;  
         }  
         Header.Append("\r\n");  
         // set the cc  
         if (message.CC.Count > 0)  
         {  
           Header.Append("Cc: ");  
           i = 0;  
           foreach (MailAddress To in message.CC)  
           {  
             Header.Append(i > 0 ? "," : "");  
             Header.Append(To.Address);  
             i++;  
           }  
           Header.Append("\r\n");  
         }  
         // set the email subject  
         Header.Append("Subject: " + message.Subject + "\r\n");  
         Header.Append("Date: ");  
         Header.Append(DateTime.Now.ToString("R"));  
         Header.Append("\r\n");  
         string MsgBody = message.Body;  
         if (!MsgBody.EndsWith("\r\n"))  
           MsgBody += "\r\n";  
         //generate a unique boundary for this email  
         var uniqueBoundary = EncodeTo64("uniqueboundary" + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));  
         Header.Append("Content-Type: multipart/alternative; boundary=" + uniqueBoundary + "\r\n");  
         Header.Append("This is a multi-part message in MIME format.\r\n");  
         // adding message body  
         SendData(s, ("DATA\r\n"));  
         if (!Check_Response(s, SMTPResponse.DATA_SUCCESS))  
         {  
           s.Close();  
           return false;  
         }  
         if (message.Attachments.Count > 0)  
         {  
           StringBuilder sb = new StringBuilder();  
           foreach (Attachment attachment in message.Attachments)  
           {  
             byte[] binaryData;  
             if (attachment != null)  
             {  
               sb.Append("--" + uniqueBoundary + "\r\n");  
               sb.Append("Content-Type: application/octet-stream; file=" + attachment.Name + "\r\n");  
               sb.Append("Content-Transfer-Encoding: base64\r\n");  
               sb.Append("Content-Disposition: attachment; filename=" + attachment.Name + "\r\n");  
               sb.Append("\r\n");  
               var fs = attachment.ContentStream;  
               binaryData = new Byte[fs.Length];  
               long bytesRead = fs.Read(binaryData, 0, (int)fs.Length);  
               fs.Close();  
               string base64String = System.Convert.ToBase64String(binaryData, 0, binaryData.Length);  
               for (int j = 0; j < base64String.Length; )  
               {  
                 int nextchunk = 100;  
                 if (base64String.Length - (j + nextchunk) < 0)  
                   nextchunk = base64String.Length - j;  
                 sb.Append(base64String.Substring(j, nextchunk));  
                 sb.Append("\r\n");  
                 j += nextchunk;  
               }  
               sb.Append("\r\n");  
             }  
           }  
           Header.Append(sb.ToString());  
         }  
         Header.Append("--" + uniqueBoundary + "\r\n");  
         // is an html email?  
         if (message.IsBodyHtml)  
         {  
           Header.Append("Content-Type: text/html; charset=\"UTF-8\"\r\n");  
           Header.Append("Content-Transfer-Encoding: 7bit\n");  
         }  
         else  
           Header.Append("Content-Type: text/plain; charset=\"UTF-8\"\r\n");  
         Header.Append("\r\n");  
         Header.Append(MsgBody);  
         Header.Append("--" + uniqueBoundary + "--\r\n");  
         Header.Append(".\r\n");  
         // send the email  
         SendData(s, Header.ToString());  
         if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))  
         {  
           s.Close();  
           return false;  
         }  
         // close the connection  
         SendData(s, "QUIT\r\n");  
         Check_Response(s, SMTPResponse.QUIT_SUCCESS);  
         s.Close();  
       }  
       return true;  
     }  
     // send a message using the socket  
     private static void SendData(Socket s, string msg)  
     {  
       byte[] _msg = Encoding.UTF8.GetBytes(msg);  
       s.Send(_msg, 0, _msg.Length, SocketFlags.None);  
     }  
     // check if the socket response watch the one expected  
     private static bool Check_Response(Socket s, SMTPResponse response_expected)  
     {  
       string sResponse;  
       int response;  
       byte[] bytes = new byte[1024];  
       s.Receive(bytes);  
       sResponse = Encoding.ASCII.GetString(bytes);  
       response = Convert.ToInt32(sResponse.Substring(0, 3));  
       if (response != (int)response_expected)  
         return false;  
       return true;  
     }  
     private string EncodeTo64(string toEncode)  
     {  
       byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);  
       string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);  
       return returnValue;  
     }  
   }  
 }  

Every time we send some data through the socket using the method SendData, we need to check the response from the server. If the answer is positive we proceed sending the next bunch of data.


lunedì 25 novembre 2013

C# - How to set the Mail From Envelope

When you send an email using System.Net.Mail you can set the field FROM but you can not set the SMTP MAIL FROM envelope. It is possible to set that value just using the MailMessage.Sender property. Here it is the code:

using (MailMessage mailMsg = new MailMessage())
{
    mailMsg.Subject = "Hello There";
    mailMsg.Body = "This is a test.";
    mailMsg.To.Add(new MailAddress("xxxxx@gmail.com"));
    mailMsg.ReplyToList.Add("replyhere@gmail.com");
    mailMsg.From = new MailAddress("me@gmail.com", "Alessandro");
    mailMsg.Sender = new MailAddress("somereturnpath@example.co.uk");
    SmtpClient client = new SmtpClient
    {
        Host = "localhost",
        DeliveryMethod = SmtpDeliveryMethod.Network
    };
 
    client.Send(mailMsg);
}

It is important to set the DeliveryMethode to "Network" in order to let the system to set the MAIL FROM envelope from the sender.

And here is the proof:




lunedì 8 luglio 2013

Pension scheme: la pensione nel Regno Unito

Lo so che magari avete appena iniziato a lavorare ma se avete programmato un futuro a lungo termine nel Regno Unito, sarebbe anche il caso di iniziare a pensare alla pensione.
Partiamo dalla pensione di stato: vi vengono detratte delle tasse dallo stipendio e parte di queste serviranno a pagare la vostra pensione. Attualmente lo stato paga £110.15 a settimana. Insomma poco piu di 400 pound al mese, un po' pochine per poter pensare di vivere in tranquillita'!




Occorre quindi che iniziate a pensare a uno schema pensionistico privato! In questo caso parliamo di un "pot" dove voi, il vostro datore di lavoro e lo stato versate una piccola quota ogni mese e che andra' a formare la vostra pensione quando deciderete  sia il caso di ritirarvi dalla vita lavorativa. Ovviamente il tutto esentasse.




Esistono diversi tipi di pensioni private. Il concetto di base rimane lo stesso ma quello che cambia e' il modo in cui i soldi "messi da parte" sono investiti. 

- Standard pension: con questo tipo di pensione il lavoratore e il datore di lavoro versano una cifra mensilmente nel pot e i soldi sono investiti da una "pension company" fino all'eta' di pensionamento
- Stakeholder pension: simile alla pensione standard ma ha condizioni piu' flessibili. La contribuzione minima e' minore, costi minori e scelte di investimento gia' definite cosi il lavoratore non ha bisogno di decidere dove investire i soldi.
- Self-invested personal pensions (Sipps): alternativa alla stakeholder pension. In questo caso potete decidere voi dove investire i vostri soldi. Ci sono servizi finanziari che vi permettono di investire i vostri soldi in aziende come Apple, Amazon ecc. Ovviamente il tutto a vostro rischio e pericolo. Probabilmente investendo pochi soldi in moltissime aziende si dovrebbero quasi azzerare i rischi garantendo un minimo di guadagno.

Ecco qui una tabella riassuntiva (fonte):
PensionCan you contribute?Can your employer contribute?Do you invest the cash?
Standard pensionYesYesYes
Stakeholder pensionYesYesYes
SippYesYesYes
Final salaryYesYesNo
State pensionYes, by paying national insuranceNoNo

Io non ho ancora deciso quale schema scegliere ma dovro' farlo presto. Inoltre vi invito a prendere tutte le informazioni che trovate  in retecon le pinze e rivolgervi sempre a qualcuno che ha esperienza nel campo perche' con la pensione non si scherza!

giovedì 4 luglio 2013

Json.Net

JSON e' diventato uno standard molto diffuso nell'ambito delle web application e sta pian piano sostituendo XML come standard per lo scambio di dati in ambito web. Per chi come me lavora con C#, trovera' molto utile la libreria Json.Net. Questa libreria permette la serializzazione e deserializzazione di oggetti JSON in maniera veloce ed intuitiva.
Come mostrato nella figura 1, le performance sono sicuramente un punto di forza di questa libreria.



Diamo ora uno sgurado piu da vicino al codice. Supponiamo di ricevere la seguente stringa e di voler estrarre i dati contenuti al suo interno:

{
    "global": {
        "TITLE": "global TITLE",
        "FIRSTNAME": "global FIRSTNAME",
        "LASTNAME": "global LASTNAME",
        "USERNAME": "global USERNAME",
        "COMPANYNAME": "global COMPANYNAME"
    }
}

Ecco il codice C#:

using Newtonsoft.Json.Linq;
namespace Test
{
      public class SavePlaceholder : Entity
     {
             public virtual IList<string> Placeholders { get; set; }
             public virtual void savePlaceholders(string json)
            {
                 this.Placeholders = new List<string>();
                 JObject jObject = JObject.Parse(json);
                 foreach (var item in jObject)
                {
                      foreach (JProperty token in item.Value)
                      {
                           var placeholder = token.Name;
                          Placeholders.Add(placeholder);
                      }
                }
           }
       }
}

Il metodo parse della classe JObject ci permette di leggere la stringa in formato JSON e serializzarla in un oggetto. Scorrendo i diversi item che formano jObject, per ogni item andiamo ad estrarre le diverse proprieta' e successivamente salviamo per ogni coppia chiave-valore soltanto la chiave. In alternativa usando token.Value avremmo potuto estrarre il valore della proprieta'. Il risultato e' la seguente lista:

TITLE
FIRSTNAME
LASTNAME
USERNAME
COMPANYNAME

Per una documentazione dettagliata e maggiori esempi vi rimando al sito ufficiale.

mercoledì 3 luglio 2013

Regex per numeri telefonici in python

Qualche giorno fa mi sono imbattuto in un problema abbastanza comune quando si lavora con python e i "regex". Prima di tutto: cos'e' un regex? Regex sta per regular expression e serve ad individuare uno specifico pattern nel testo (cifre, indirizzo email, codice postale). Per una lettura approfondita vi rimando a wikipedia.
Il mio problema era molto semplice: data la descrizione di un annuncio per proprieta' mobiliari, dovevo creare un regex in python per eliminare i numeri telefonici dalla descrizione.
Ecco qui la soluzione:

re.sub(r'(\d\.?\s*){8,}', '------', content )

Breve spiegazione: il metodo sub della libreria re sostituisce tutte le occorrenze di una stringa con un altra stringa all'interno di un testo.La stringa "\d" identifica una qualsiasi cifra decimale; il ? ci dice che l'espressione precedente puo' apparire 0 o 1 volte (in questo caso l'espressione precedente e' un punto); la stringa"\s" identifica un qualsiasi whitespace, cioe' un semplice spazio, e l'asterisco indica che l'espressione precedente puo' essere ripetuta n volte; infine {8,} ci dice che il nostro regex dovra' trovare la struttura precedentemente specificata almeno 8 volte (cioe' il codice definito tra parentesi tonde).
Riassumendo il nostro regex "matchera'" tutte quelle stringhe che contengono una cifra da 0 a 9 seguita o non seguita da un punto e seguita da 0 o piu' spazi bianchi. Il tutto ripetuto per 8 volte. Quindi il nostro regex trovera' un numero telefonico del tipo "07592345678" oppure "02.45.67.78" ma non sostituira' una stringa del tipo "10.000" che potrebbe essere un importo.

Per ulteriori informazioni vi rimando alla documentazione ufficiale di python per le espressioni regolari.

domenica 9 giugno 2013

Tra Regno Unito e Germania quei paesi dove trovi posto

...C'è infine anche spazio per gli informatici. Nel Regno Unito, sempre a maggio 2013, i selezionatori delle imprese hanno messo a disposizione 27.290 posti. In Germania, in questo settore, le richieste arrivavano a 11.300 figure mentre in Belgio si è arrivati a 2.500 posti.

Ecco l'articolo originale.

giovedì 6 giugno 2013

Italiani a Londra - Sono uno sviluppatore software..

Mia breve intervista su Londra news. Link originale qui

Da quanto tempo sei in UK e come ti trovi?
Mi sono trasferito in un freddo Febbraio 2012. A parte le classiche condizioni climatiche che a volte ti mettono tristezza, per il resto sto davvero bene.
Che tipo di lavoro fai e come l’hai trovato?
Sono uno sviluppatore software per una piccola azienda di Londra con ufficio nella centrale Barbican. L’ho trovato su gumtree dopo una ricerca durata 8 mesi. Ho fatto altri lavori nel frattempo (montavo computer da zero i primi mesi lavoravo per EAT servendo i clienti alle casse o facendo panini).
Foto: LicenseAttributionShare Alike Some rights reserved by fsse8info
Secondo te quali sono i principali lati negativi di Londra/UK?
Il clima in assoluto. Non vedo l’ora di andare in vacanza questa estate in sardegna e stare tutto il giorno al sole! E ovviamente i costi di affitti e trasporti!
E quali sono i lati positivi?
Tutto il resto ovviamente! Salari migliori, persone piu’ aperte mentalmente, diverse culture che si fondono, maggior senso civico delle persone, innovazione in tutto, possibilita’ di crescite professionali infinite e molto altro
Se dovessi rifare tutto verresti ancora a Londra/UK?
Assolutamente senza dubbio si.
Ritorneresti in Italia?
Sono tornato a Foggia, mia citta’ natale, per le feste pasquali. La situazione in generale sta peggiorando al sud ma non solo. Disoccupazione alle stelle, negozi che chiudono uno dopo l’altro, citta’ lasciate allo sbaraglio per mancanza di fondi. No non penso di tornare se non per magari godermi la vecchiaia in qualche posto di mare.
Che consigli daresti a chi sta pensando di trasferirsi a Londra/UK?
Di informarsi tanto(ho pubblicato alcune info sul mio blog). Di avere un bel po’ di soldi almeno all’inzio e di armarsi di tanta forza di volonta’. Londra da’ sempre un opportunita’ a tutti!