【问题标题】:Sending email MVC4 C#发送电子邮件 MVC4 C#
【发布时间】:2013-06-18 05:05:56
【问题描述】:

我正在尝试在操作中发送电子邮件。但是,该操作总是返回一个空白屏幕。

查看:

<% using(Html.BeginForm("Sendlink", "Home")) %>
    <% { %>
     <input type="text" id="toemail" value="" />
        <input type="submit" value="Send" />
    <% } %>

控制器:

public ActionResult Sendlink()
{
    return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Sendlink(FormCollection formCollection)
{
    try
    {
        string message = Session["link"].ToString();
        string toemail = formCollection["toemail"];
        MailEngine.Send("mail@mail.com", toemail, "link", message);
        return RedirectToAction("CanvasShare");
    }
    catch
    {

    }
    return null;
}

类邮件引擎:

public static void Send(string from, string to, string subject, string body)
{
    try
    {
        MailMessage mail = new MailMessage(from, to, subject, body);
        SmtpClient client = new SmtpClient("smtp.mymail.com");
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        client.EnableSsl = false;
        client.Send(mail);
    }
    catch
    {

    }
}

【问题讨论】:

  • 首先我不会使用FormCollection作为参数,而是使用SendLink(string toemail)。查看 ModelBinding 了解更多信息。
  • 您的 MailEngine.Send 可能会引发异常,导致您的 SendLink 操作返回 null 而不是返回 af 视图。当心空的 catch 块。
  • 你试过调试器吗?
  • 我将 Formcollection 更改为字符串 toemail,在我调试时,toemail 为空。
  • 您需要将输入的name属性设置为:"tomail"才能使其可绑定。

标签: c# asp.net-mvc html-email


【解决方案1】:

您在应用程序中使用了空的 catch 块。这确实不是一个好主意,要对此进行更深入的讨论,请参阅Why are empty catch blocks a bad idea? 和相关问题。

您似乎发生了以下情况:

  • Sendlink(FormCollection formCollection) 方法的 try 块内某处引发异常。此异常似乎源自 RedirectToAction("CanvasShare") 调用,因为该 try 块内的所有其他调用都不会生成异常。 (特别是因为您抑制了 MailEngine.Send 方法引发的异常。)
  • Sendlink(FormCollection formCollection) 中的空 catch 块被调用。这是您应该生成错误消息并将其显示给用户的地方。但是,您决定将其留空,这样没人知道出了什么问题以及发生了什么。
  • 控制流到达return null; 方法中的Sendlink(FormCollection formCollection) 语句。我的猜测是你把它放在那里是因为编译器抱怨缺少返回值。现在返回此 null 并导致呈现一个空视图。

显而易见的解决方法是检查RedirectToAction 并找出它引发异常的原因。此异常可能表明您的代码或应用程序存在问题,您需要采取措施防止它发生。

下一个修复是在您的应用程序中实际实现错误处理。删除所有空的catch 块并考虑是否要抛出异常或者是否要立即处理它。然而,忽略它几乎不是一个好主意。

为了说明您的应用程序中的问题:如果RedirectToAction 中的异常没有被抛出,您的电子邮件发送可能仍然失败。但是,您的 UI 没有任何方法可以发现出现问题,因为您忽略了 MailClient.Send 方法中的异常。如果您将其交付到生产环境,电子邮件发送将无声无息地失败,您的客户会想知道为什么他们从未收到过电子邮件。然后,您将很难找出实际问题是什么以及发生在哪里。

【讨论】:

  • 非常感谢克里斯,这对在我的代码中实现非常有用。
【解决方案2】:

toemail 将始终为空。

您需要将输入的name 属性设置为:"toemail" 以使其可绑定。

<input type="text" id="toemail" name="toemail"  />

尽管如此,正如其他人所说,使用空的 catch 语句确实不是一个好主意。它隐藏了一个潜在的错误。与您的情况一样,try catch 块中有一个隐藏异常导致空操作结果,因此出现了空白屏幕。

有几个选项,如何在 ASP MVC 中处理异常。我最喜欢的是异常过滤器和&lt;CustomErrors mode="On"/&gt;web.config 设置的组合。

protected override void OnException(ExceptionContext filterContext)
{
    base.OnException(filterContext);

    if (filterContext.HttpContext.IsCustomErrorEnabled)
    {
        if (filterContext.Exception is SecurityException)
        {
            filterContext.ExceptionHandled = true;
            filterContext.Result = View("FriendlyError");
            //log the exception etc...
        }
    }
}

因此,当启用自定义错误时,您可以在生产环境中返回友好的错误屏幕,或者在调试时禁用它以查看实际异常。

【讨论】:

  • 虽然这肯定是发送电子邮件的问题,但为什么会导致返回空白屏幕?
  • @Chris:当toemail 为空时,邮件引擎很可能会抛出异常。所以动作结果是 null -> 空白屏幕。
  • MailEngine 永远不会抛出异常,因为所有异常都在 MailEngine.Send 中捕获。
  • 你说得对,我忽略了它。另一个可能抛出NullReferenceExceptionstring message = Session["link"].ToString();
  • 是的,但这仍然不受在 input 标签上添加 name 属性的影响。我想知道为什么这会促使行为发生变化。
猜你喜欢
  • 2012-11-17
  • 2015-03-05
  • 2014-10-31
  • 2016-04-17
  • 2012-07-27
  • 2018-07-24
  • 2020-05-23
  • 1970-01-01
相关资源
最近更新 更多