You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.Net MVC EF6实现点击按钮批量调用控制器方法给学生发邮件

没问题,我帮你一步步实现这个批量发邮件的功能,分几个核心环节来拆解,保证清晰易懂:

1. 先定义一个视图模型(ViewModel)

因为你需要收集发件人信息,同时关联学生列表,所以先创建一个专门的ViewModel来封装这些数据,方便在视图和控制器之间传递:

public class SendEmailViewModel
{
    [Required(ErrorMessage = "请输入你的姓名")]
    public string SenderName { get; set; }

    [Required(ErrorMessage = "请输入你的邮箱")]
    [EmailAddress(ErrorMessage = "邮箱格式不正确")]
    public string SenderEmail { get; set; }

    [Required(ErrorMessage = "请输入消息内容")]
    public string MessageContent { get; set; }

    // 存储待发送的学生列表(从EF查询得到)
    public List<mytable> Students { get; set; }
}
2. 改造原有的Project控制器方法

把原来的Project方法改成返回ViewModel,这样视图能拿到学生列表和发件人表单的绑定数据:

public ActionResult Project(int? id)
{
    // 替换成你的EF查询逻辑,根据id获取对应的学生列表
    var students = db.mytable.Where(s => s.ProjectId == id).ToList();

    var viewModel = new SendEmailViewModel
    {
        Students = students
        // 可选:如果需要默认填充发件人信息,在这里赋值
    };

    return View(viewModel);
}
3. 设计视图页面(Project.cshtml)

视图需要包含发件人信息表单、学生列表预览,以及提交按钮。注意用POST方式提交表单,确保数据安全:

@model YourNamespace.SendEmailViewModel

@{
    ViewBag.Title = "批量发送学生邮件";
}

<!-- 显示发送结果提示 -->
@if (TempData["SendResult"] != null)
{
    <div class="alert alert-info">@TempData["SendResult"]</div>
}

<h2>给学生发送消息</h2>

@using (Html.BeginForm("SendBulkEmails", "YourControllerName", FormMethod.Post, new { @class = "form-horizontal" }))
{
    @Html.AntiForgeryToken()

    <!-- 发件人姓名 -->
    <div class="form-group">
        @Html.LabelFor(m => m.SenderName, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.SenderName, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.SenderName, "", new { @class = "text-danger" })
        </div>
    </div>

    <!-- 发件人邮箱 -->
    <div class="form-group">
        @Html.LabelFor(m => m.SenderEmail, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.SenderEmail, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.SenderEmail, "", new { @class = "text-danger" })
        </div>
    </div>

    <!-- 消息内容 -->
    <div class="form-group">
        @Html.LabelFor(m => m.MessageContent, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextAreaFor(m => m.MessageContent, new { @class = "form-control", rows = 6 })
            @Html.ValidationMessageFor(m => m.MessageContent, "", new { @class = "text-danger" })
        </div>
    </div>

    <!-- 隐藏传递Project的id,用于控制器重新查询学生列表(避免前端篡改) -->
    @Html.Hidden("id", ViewContext.RouteData.Values["id"])

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <button type="submit" class="btn btn-primary">发送邮件</button>
        </div>
    </div>
}

<!-- 预览待发送的学生列表 -->
<h3>待发送学生清单</h3>
<table class="table table-striped">
    <thead>
        <tr>
            <th>学生姓名</th>
            <th>邮箱地址</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var student in Model.Students)
        {
            <tr>
                <td>@student.Name</td>
                <td>@student.Email</td>
            </tr>
        }
    </tbody>
</table>
4. 实现批量发送的控制器方法,循环调用Contact

首先假设你已经有了单封邮件发送的Contact方法,我们基于它扩展批量发送逻辑:

先完善单封邮件的Contact方法(异步版本更友好)

// 异步发送单封邮件的方法
private async Task<bool> SendSingleEmail(string senderName, string senderEmail, string studentEmail, string message)
{
    try
    {
        var mail = new System.Net.Mail.MailMessage();
        mail.From = new System.Net.Mail.MailAddress(senderEmail, senderName);
        mail.To.Add(studentEmail);
        mail.Subject = $"来自{senderName}的通知";
        mail.Body = message;
        mail.IsBodyHtml = false; // 若需要HTML内容,改为true

        // 替换成你的SMTP配置(比如QQ/163邮箱的SMTP服务器)
        using (var smtp = new System.Net.Mail.SmtpClient("smtp.qq.com", 587))
        {
            smtp.Credentials = new System.Net.NetworkCredential("你的邮箱账号", "SMTP授权码");
            smtp.EnableSsl = true;
            await smtp.SendMailAsync(mail);
        }
        return true;
    }
    catch (Exception ex)
    {
        // 这里建议记录日志,比如用Log4net/NLog记录发送失败的异常
        // Log.Error($"给{studentEmail}发送邮件失败:{ex.Message}");
        return false;
    }
}

添加批量发送的Action方法

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SendBulkEmails(SendEmailViewModel model, int? id)
{
    // 先验证表单数据是否合法
    if (!ModelState.IsValid)
    {
        model.Students = db.mytable.Where(s => s.ProjectId == id).ToList();
        return View("Project", model);
    }

    // 重新从数据库查询学生列表(安全起见,不依赖前端传递的数据)
    var students = db.mytable.Where(s => s.ProjectId == id).ToList();
    int successCount = 0;
    int failCount = 0;

    // 循环给每个学生发送邮件
    foreach (var student in students)
    {
        var isSuccess = await SendSingleEmail(model.SenderName, model.SenderEmail, student.Email, model.MessageContent);
        if (isSuccess)
            successCount++;
        else
            failCount++;
    }

    // 把发送结果通过TempData传递到视图
    TempData["SendResult"] = $"邮件发送完成:成功{successCount}封,失败{failCount}封";
    return RedirectToAction("Project", new { id = id });
}
几个关键注意事项
  • SMTP配置:不同邮箱的SMTP服务器和端口不一样,比如QQ邮箱是smtp.qq.com:587,需要开启POP3/SMTP服务并生成授权码(不要用登录密码)。
  • 异步处理:用async/await避免长时间阻塞请求,提升用户体验,尤其是学生数量较多时。
  • 安全问题:控制器里重新查询学生列表,而不是依赖前端传递的邮箱,防止恶意篡改收件人。
  • 性能优化:如果学生数量极大,可以考虑用Parallel.ForEach并行发送,但要注意SMTP服务器的并发限制,避免被封禁。

内容的提问来源于stack exchange,提问作者Rawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:31:58