none
Invio di una mail con ASP.NET MVC 3 RRS feed

  • Domanda

  • Salve, ho un problema che non riesco a risolvere perchè ancora non so muovermi bene con MVC 3. Ho un semplice form "contatti" che mi permette di inserire dei dati:

    nome, cognome telefono ecc. e questi vengono salvati correttamente sul database.

    utilizzo EF code first e il modello strongly-tiped create di mvc.

    Ora io vorrei che questi dati vengano spediti tramite una E-mail al mio indirizzo di posta elettronica. Dove sta il problema? Su WebForms usavo un codice del genere.

     

    Public Shared Sub SendMail(ByVal Destinatari As String, ByVal Oggetto As String, ByVal Messaggio1 As String, Optional ByVal HTML As Boolean = False)
    
                Try
                    Dim myMail As New MailMessage()
                    Dim SMTP As String = System.Configuration.ConfigurationManager.AppSettings("SMTP").ToString
                    Dim Address As String = "mittente@live.it"
                    Dim DisplayName As String = "ciao"
                    Dim Subject As String = "Richiesta di informazioni"
                    Dim OutSmtp As New SmtpClient(SMTP)
                    OutSmtp.Credentials = New NetworkCredential("mittente@live.it", "password")
                    Dim Mittente As New MailAddress(Address, DisplayName)
                    Dim aDestinatari As String() = Destinatari.Split(",")
                    myMail.From = Mittente
                    myMail.Subject = Subject
                    myMail.IsBodyHtml = HTML
                    myMail.Body = Messaggio1
                    For i = 0 To aDestinatari.Length - 1
                        myMail.To.Add(aDestinatari(i))
                    Next
                    OutSmtp.DeliveryMethod = SmtpDeliveryMethod.Network
                    OutSmtp.Send(myMail)
                Catch ex As Exception
                End Try
    
            End Sub
    
        Protected Sub Invia_Click(sender As Object, e As System.EventArgs) Handles Invia.Click
    
            Dim Oggetto As String = "Richiesta di informazioni"
            Dim messaggio1 As String = "Nome:" & Nome.Text & ";" & "Cognome:" & "" & Cognome.Text & ";" & "Telefono:" & "" & Telefono.Text & ";" & "E-Mail:" & "" & Email.Text & ";" & "Messaggio:" & "" & Messaggio.Text
            SendMail("info@destinatario.it", Oggetto, messaggio1, False)
    

     


    So che non è ottimizzato e che può essere scritto meglio, ma bene o male su webforms funzionava. Oggi ho girato un po per la rete per trovare delle soluzioni e ne ho trovate svariate fai-da-te però non mi convicevano molto e quindi ho deciso di scrivere su MDSN. Il sostanza la mia domanda é: un codice simile, togliendo ovviamente l'evento del bottone, è possibile che funzioni anche su MVC? Ci sono dei tool esterni che potrebbero facilitarmi con la scrittura del mio codice? Grazie a tutti.

    PS. non avendo molta esperienza con questo framework mi trovo in difficoltà a gestire i controlli piuttosto che gli eventi dei web server controls. E' pura abitudine, ma volendo, non avrei potuto riapplicare questo codice su MVC perchè non so ancora come richiamarlo.

     

    Saluti



    giovedì 22 settembre 2011 16:06

Risposte

  • Sì! :)

    Non ricordo se ti avevo già postato questo esempio: http://sample.codeplex.com/wikipage?title=MVC%20layered%20application

    Vedi come viene usato Automapper, è molto semplice, specialmente se la classe del Model ha la stessa struttura (vedi proprietà) di quella del Domain.
    Matteo Migliore

    Bloghttp://blogs.ugidotnet.org/matteomigliore
    Twitterhttp://twitter.com/matteomigliore
    CodePlex
    sabato 24 settembre 2011 12:41
  • Riapro questo topic dopo svariato tempo perchè ho trovato una soluzione a parer mio molto semplice e intuitiva, da usare in alternativa ad automapper.

    http://razorengine.codeplex.com/

    scaricate l'engine di razor e implementatelo nella vostra applicazione.

    ora modificate il vostro controller prendendo spunto da questo (ho incollato solo la parte di post)

            [HttpPost]
            public ActionResult Index(Contact contact)
            {
                if (ModelState.IsValid)
                {
                   
                    db.Contatties.Add(contact);
                    db.SaveChanges();
                    SendTemplateEmail("esempi@esempio.it", "destinatario@destinatario.it", "Richiesta Informazioni", "templatePath", contact);

                    return RedirectToAction("Index");
                }

                return View(contact);
            }

            public void SendTemplateEmail(string from, string to, string subject, string templatePath, Contact contact)
            {
                    MailMessage message = new MailMessage();

                    // Mittente del messaggio
                    message.From = (new MailAddress(from));

                    // Uno o più destinatari del messaggio
                    message.To.Add(new MailAddress(to));
                    // Oggetto del messaggio
                    message.Subject = subject;
                    message.SubjectEncoding = System.Text.Encoding.GetEncoding("iso-8859-15");

                    // Corpo del messaggio
                    message.Body = GetEmailBody(templatePath, contact);
                    message.BodyEncoding = System.Text.Encoding.GetEncoding("iso-8859-15");

                    // Formato del corpo del messaggio
                    message.IsBodyHtml = true;

                    try
                    {
                        // Invio del messaggio di posta elettronica
                        SmtpClient server = new SmtpClient();
                        server.Send(message);
                    }

                    catch (SmtpException ex)
                    {
                    }
            }

            public string GetEmailBody(string templatePath, Contact contact)
            {

              
                string template = Bevenuto</h1> <p><strong>@Model.Mail</strong> @Model.Name @Model.Surname @Model.Phone @Model.Post!

                /*USARE QUESTA STRINGA SE SI VUOLE RENDERIZZARE LA MAIL CON UNA VOSTRA VIEW
                string template = System.IO.File.ReadAllText(Server.MapPath("/App_Code/EMail.cshtml"));*/
                return Razor.Parse(template, new { contact.Name, contact.Surname, contact.Mail, contact.Phone, contact.Post });


            }
        }
    }

     

    la differenza è nel metodo GetEmailBody: infatti tramite questo metodo possiamo fare in modo che al post della nostra pagina, i dati vengano inseriti nel database e venga inviata una mail con gli stessi dati.

    la variabile template fa riferimento al nostro model. Il testo può essere personalizzato tramite html. Se si vuole andare oltre, si può fare riferimento ad una view personalizzata come ho scritto sotto. Ecco una semplice struttura

    <html>
    <head>
        <title>WelcomeEmail</title>
        <style>
            body
            {
                background-color:#1D1D1D;
                }
            h1
            {
                color:Red;
                float:right;
               
                }
                p
                {
                    color:Green;
                    }
        </style>
    </head>
    <body>
        <h1>
          Bevenuto</h1> <p><strong>@Model.Mail</strong> @Model.Name @Model.Surname @Model.Phone @Model.Post!
        </p>
    </body>
    </html>

     

    Grazie per l'attenzione e buon lavoro a tutti.

     

    Saluti


    domenica 27 novembre 2011 15:55

Tutte le risposte

  • Certo, in MVC funziona senza problemi.

    Le differenze sono:
    1. anzichè accedere direttamente ai controlli (TextBox etc...) utilizzi i Model o ViewModel, la classe in binding
    2. anzichè intercettare "l'evento" click del button, un controllo <input type="submit" /> chiama l'Action di un Controller

    Qui trovi un esempio:
    http://weblogs.asp.net/andrewrea/archive/2008/06/05/a-simple-mvc-preview-3-contact-form-custom-htmlhelper-and-model-example.aspx

    O qui:
    http://blog.bobcravens.com/2009/08/asp-net-mvc-contact-form/

    In questo secondo esempio la validazione viene fatta implementando l'interfaccia IDataErrorInfo nella classe del Model (ContactFormModel) ma puoi utilizzare tranquillamente DataAnnotations, se ti trovi meglio.
    Matteo Migliore

    Bloghttp://blogs.ugidotnet.org/matteomigliore
    Twitterhttp://twitter.com/matteomigliore
    CodePlex
    giovedì 22 settembre 2011 18:20
  • Grazie Matteo, ho seguito pari passo il secondo esempio ma quando cerco di inviare la mail mi restituisce un errore 404. Non so da che cosa dipenda, ora ti posto il sorgente:

    EDIT: CODICE CONFUSIONARIO, NON LO POSTO PERCHE' E' INUTILIZZABILE

    Il codice è parecchio :D grazie anche se alla fine è il template generato da VS.

    ps: il model contact è per l'inserimento nel database, se ne aggiungo altri poi la form da un errore di sintassi






    giovedì 22 settembre 2011 20:07
  • Si dopo una nottata ci sono riuscito c'è ancora un problema però :D

    Lascia perdere il codice che ho postato prima, sono riuscito ad utilizzare quello iniziale. Sono ad inviare la mail però il corpo del messaggio non era quello dei controlli. Il problema che rimane è questo: fare in modo che il corpo della mail siano i controlli della view.

     

    Prima mi hai scritto che invece di richiamare le textbox con i vari ID devo farlo con i model....

    Per richiamare i model, dovrei prima creare un classe nella cartella model con i vari campi, generare un controller che si basi su quel model e infine creare una semplice view di inserimento? Anche se c'è scritto nell'esempio è meglio chiedere :). Grazie

     

    Saluti

     



    venerdì 23 settembre 2011 09:24
  • Sì è esattamente così :). Il model lo plasmi secondo le tue necessità.

    Poi puoi passare all'helper Ajax anzichè Html, che consente di creare form asincroni.
    Matteo Migliore

    Bloghttp://blogs.ugidotnet.org/matteomigliore
    Twitterhttp://twitter.com/matteomigliore
    CodePlex
    venerdì 23 settembre 2011 09:30
  • Ma se io ho una View che si basa già sul model per l'inserimento nel database, come faccio per far passare anche quello della mail? Devo passare gli argomenti tramite Html.BeginForm()?

     

    Grazie

     

    venerdì 23 settembre 2011 11:20
  • Spiegati meglio :).

    Hai due model diversi e vuoi usare la stessa view?


    Matteo Migliore

    Bloghttp://blogs.ugidotnet.org/matteomigliore
    Twitterhttp://twitter.com/matteomigliore
    CodePlex
    venerdì 23 settembre 2011 11:24
  • Si un model per la mail, come abbiamo detto prima e uno per far si che quei dati vengano inseriti nel database (tramite entity framework) in questo caso la mia view è già predisposta per l'inserimento nel database, è possibile far coesistere entrambi nella stessa view? :)

     


    venerdì 23 settembre 2011 12:05
  • Allora, in questo caso hai solo una View e solo un Model. Giusto?

    Ti basta usare Automapper per convertire il model nella classe di dominio (la entity di EF).

    Ti torna?
    Matteo Migliore

    Bloghttp://blogs.ugidotnet.org/matteomigliore
    Twitterhttp://twitter.com/matteomigliore
    CodePlex
    venerdì 23 settembre 2011 16:09
  • http://bengtbe.com/blog/2009/04/14/using-automapper-to-map-view-models-in-asp-net-mvc/

     

    Intendi una cosa del genere? posso provarci! Grazie

    sabato 24 settembre 2011 12:17
  • Sì! :)

    Non ricordo se ti avevo già postato questo esempio: http://sample.codeplex.com/wikipage?title=MVC%20layered%20application

    Vedi come viene usato Automapper, è molto semplice, specialmente se la classe del Model ha la stessa struttura (vedi proprietà) di quella del Domain.
    Matteo Migliore

    Bloghttp://blogs.ugidotnet.org/matteomigliore
    Twitterhttp://twitter.com/matteomigliore
    CodePlex
    sabato 24 settembre 2011 12:41
  • Riapro questo topic dopo svariato tempo perchè ho trovato una soluzione a parer mio molto semplice e intuitiva, da usare in alternativa ad automapper.

    http://razorengine.codeplex.com/

    scaricate l'engine di razor e implementatelo nella vostra applicazione.

    ora modificate il vostro controller prendendo spunto da questo (ho incollato solo la parte di post)

            [HttpPost]
            public ActionResult Index(Contact contact)
            {
                if (ModelState.IsValid)
                {
                   
                    db.Contatties.Add(contact);
                    db.SaveChanges();
                    SendTemplateEmail("esempi@esempio.it", "destinatario@destinatario.it", "Richiesta Informazioni", "templatePath", contact);

                    return RedirectToAction("Index");
                }

                return View(contact);
            }

            public void SendTemplateEmail(string from, string to, string subject, string templatePath, Contact contact)
            {
                    MailMessage message = new MailMessage();

                    // Mittente del messaggio
                    message.From = (new MailAddress(from));

                    // Uno o più destinatari del messaggio
                    message.To.Add(new MailAddress(to));
                    // Oggetto del messaggio
                    message.Subject = subject;
                    message.SubjectEncoding = System.Text.Encoding.GetEncoding("iso-8859-15");

                    // Corpo del messaggio
                    message.Body = GetEmailBody(templatePath, contact);
                    message.BodyEncoding = System.Text.Encoding.GetEncoding("iso-8859-15");

                    // Formato del corpo del messaggio
                    message.IsBodyHtml = true;

                    try
                    {
                        // Invio del messaggio di posta elettronica
                        SmtpClient server = new SmtpClient();
                        server.Send(message);
                    }

                    catch (SmtpException ex)
                    {
                    }
            }

            public string GetEmailBody(string templatePath, Contact contact)
            {

              
                string template = Bevenuto</h1> <p><strong>@Model.Mail</strong> @Model.Name @Model.Surname @Model.Phone @Model.Post!

                /*USARE QUESTA STRINGA SE SI VUOLE RENDERIZZARE LA MAIL CON UNA VOSTRA VIEW
                string template = System.IO.File.ReadAllText(Server.MapPath("/App_Code/EMail.cshtml"));*/
                return Razor.Parse(template, new { contact.Name, contact.Surname, contact.Mail, contact.Phone, contact.Post });


            }
        }
    }

     

    la differenza è nel metodo GetEmailBody: infatti tramite questo metodo possiamo fare in modo che al post della nostra pagina, i dati vengano inseriti nel database e venga inviata una mail con gli stessi dati.

    la variabile template fa riferimento al nostro model. Il testo può essere personalizzato tramite html. Se si vuole andare oltre, si può fare riferimento ad una view personalizzata come ho scritto sotto. Ecco una semplice struttura

    <html>
    <head>
        <title>WelcomeEmail</title>
        <style>
            body
            {
                background-color:#1D1D1D;
                }
            h1
            {
                color:Red;
                float:right;
               
                }
                p
                {
                    color:Green;
                    }
        </style>
    </head>
    <body>
        <h1>
          Bevenuto</h1> <p><strong>@Model.Mail</strong> @Model.Name @Model.Surname @Model.Phone @Model.Post!
        </p>
    </body>
    </html>

     

    Grazie per l'attenzione e buon lavoro a tutti.

     

    Saluti


    domenica 27 novembre 2011 15:55