从用户输入生成电子邮件正文,从控制器发送电子邮件?

Posted

技术标签:

【中文标题】从用户输入生成电子邮件正文,从控制器发送电子邮件?【英文标题】:Generate email body from user input, send email from controller? 【发布时间】:2018-12-21 15:38:29 【问题描述】:

基本上,我有一个 html 表单,我想从中获取用户输入,生成电子邮件正文,然后发送电子邮件。我以前从未编写过这样的程序,所以过去几天我一直在研究从网站发送电子邮件的不同方法,但我发现的示例都与我的确切情况无关。用我发现的不同方法鬼混也没有结果。

就目前而言,我有一个声明每个字符串的模型:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace myWebsite.Models

    public class ServiceRequest
    
        [Key]
        public int serviceRequestID  get; set; 
        [Required]
        public string serviceRequestName  get; set; 
        [Required]
        public string serviceRequestEmail  get; set; 
        public string serviceRequestCompany  get; set; 
        public string serviceRequestAddress  get; set; 
        [Required]
        public string serviceType  get; set; 
        public string serviceRequestCity  get; set; 
        public string serviceRequestState  get; set; 
        public string serviceRequestZip  get; set; 
        [Required]
        public string serviceRequestNumber  get; set; 
        public string serviceRequestComments  get; set; 

    

然后在视图中,我使用 @html 帮助器创建了表单,将模型中的字符串链接到用户输入字段:

@model myWebsite.ServiceRequest

@using (Html.BeginForm("Email", "ServiceRequestsController", FormMethod.Post))

    <div class="servicesReq">
        <div class="serviceReqForm">
            <div class="col-left">
                <label>
                    <span class="required">* </span><span>Name:</span><br />
                    @Html.TextBoxFor(model => model.serviceRequestName)
                </label><br />
                        <label>
                            <span class="required">* </span><span>Email:</span><br />
                            @Html.TextBoxFor(model => model.serviceRequestEmail)
                        </label><br />
                <label>
                    <span>Company:</span><br />
                    @Html.TextBoxFor(model => model.serviceRequestCompany)
                </label><br />
                <label>
                    <span>Address:</span><br />
                    @Html.TextBoxFor(model => model.serviceRequestAddress)
                </label><br /><br />
            </div>
            <div class="serviceTypeGrid">
                <span class="required">* </span><span>Please choose what type of servicing you require:</span><br /><br />
            </div>
            <div class="col-left2">
                <label class="serviceType">
                    @Html.RadioButton("serviceType", "Electrical") Electrical<br/>
                    @Html.RadioButton("serviceType", "Lighting") Lighting<br />
                    @Html.RadioButton("serviceType", "Energy") Energy<br />
                    @Html.RadioButton("serviceType", "Multiple") Multiple
                </label><br /><br />
            </div>
            <div class="col-right">
                <label>
                    <span>City:</span><br />
                    @Html.TextBoxFor(model => model.serviceRequestCity)
                </label><br />
                <label>
                    <span>State:</span><br />
                    @Html.TextBoxFor(model => model.serviceRequestState)
                </label><br />
                <label>
                    <span>Zip Code:</span><br />
                    @Html.TextBoxFor(model => model.serviceRequestZip)
                </label><br />
                <label>
                    <span class="required">* </span><span>Phone Number:</span><br />
                    @Html.TextBoxFor(model => model.serviceRequestNumber)
                </label><br />
            </div>
            <label class="commentText">
                <span>Comments:</span><br />
                @Html.TextAreaFor(model => model.serviceRequestComments, new  @class = "servReqComment" )
            </label>
            <div class="formSubmitButton">
                <input type="submit" value="Submit" /><br />
                <br />
            </div>
        </div>

    </div>

最后是我的控制器逻辑 - 这就是我几乎完全迷失的地方:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using myWebsite.Models;

namespace myWebsite.Controllers

    public class ServiceRequestsController : Controller
    
        private CuttingEdgeWebsite2_0Context db = new CuttingEdgeWebsite2_0Context();

        // GET: ServiceRequests
        public ActionResult ServiceRequest()
        
            return View();
        

    

正如我之前所说,我已经查找了几种不同的方法,但它们都涉及对电子邮件正文进行硬编码。我用我有限的知识尝试过的一切,我无法从表单上的用户输入生成正文。虽然我对如何实际发送邮件有某种想法,但对该过程的任何深入澄清也将非常有帮助。如果有任何我未在此处提供的信息可能对您有用,请告诉我。

【问题讨论】:

这里有很多东西:构建邮件正文、创建和发送邮件消息,以及在控制器中执行此操作。我认为你应该把它分解,一次只看一件。我要做的第一件事是确定您希望您的电子邮件采用什么格式(html 格式与否、硬编码文本等)。最终,您必须创建一个包含电子邮件正文的字符串,因此您应该使用一种方法来接受传入对象并返回电子邮件正文的字符串对象。 【参考方案1】:

这应该让你开始。以编程方式发送电子邮件有(至少)四个属性。它们是 fromaddres、toaddress、subject 和 body。

在您的表单中,您将希望利用验证摘要。这向用户提供了验证反馈。只需插入

@Html.ValidationSummary(true, "", new @class = "text-danger" )

就在您的 BeginForm 行之后

根据您的代码,这种事情会起作用。 在您的控制器中,您需要一种方法来处理表单数据的发布和一些发送电子邮件的方法(为了良好的设计,应该采用单独的方法)。

[HttpPost]    
public async Task Email(ServiceRequest servicerequest)

    try
    
        string from = "youremailadress@gmail.com"
        string to = servicerequest.serviceRequestEmail;
        string subject = servicerequest.serviceType;
        //it's up to you what you want to put in the body
        string body = String.Format("city:0\n\nComments:1\n\n
        PhoneNumber\n\n",serviceRequest.serviceRequestCity, 
        serviceRequest.serviceRequestComments, serviceRequest.serviceRequestNumber);
        string email = System.Configuration.ConfigurationManager.AppSettings["email"];
        string password = 
            System.Configuration.ConfigurationManager.AppSettings["emailpassword"];
        string server = 
            System.Configuration.ConfigurationManager.AppSettings["emailserver"];
        string emailport = 
            System.Configuration.ConfigurationManager.AppSettings["emailport"];
        int port = Int32.Parse(emailport);
        var client = new SmtpClient(server, port)
        
            Credentials = new NetworkCredential(email, password),
            EnableSsl = true
        ;
        await client.SendMailAsync("from", to, subject, body);
        Console.WriteLine("Sent");
    
    catch (Exception e)
    
       Console.WriteLine(String.Format("Error occured at 0. Full stack trace of error 1", System.DateTime.Now.ToString(),e.ToString()));
    

【讨论】:

你为什么要做一个空的catch块? @Mason 因为捕获异常与问题无关。 如果不相关,你为什么要放一个try/catch? 为什么?如果您不打算做任何事情,为什么还要尝试捕获?尤其是空的try catch。您的代码将被新的编码人员看到。教他们正确,不要在代码中乱扔不做任何事情的 try catch。让人们尽早养成良好的习惯。 好的,已修复。我同意空的 try...catch 通常会忽略应该处理的错误情况。但不总是。在某些情况下,例如在处理与远程服务器的连接时,例如 tcp/ip 远程处理,由低级通信引起的错误情况是无关紧要的,无论原因如何都需要重试操作。总之,更新了

以上是关于从用户输入生成电子邮件正文,从控制器发送电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

Gmail API 仍然使用从 HTML 自动生成的替代正文部分替换 text/plain 替代正文部分

如何通过单独的联系表单将 HTML 输入从页面发送给用户

从原始正文发送邮件以进行测试

从 uitableview 填充电子邮件正文的最佳方法

从电子邮件正文调用 Win32 应用程序

Mailkit - 接收从苹果邮件发送的消息时没有附件或 html 正文