发送电子邮件 MVC4 C#

4

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

视图:

<% 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;
}

MailEngine类:

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以获取更多信息。 - Dirk Boer
2
你的MailEngine.Send可能会抛出异常,导致你的SendLink操作返回null而不是返回视图。要注意空的catch块。 - Jakob Christensen
为了使其可绑定,您需要将输入的name属性设置为:“tomail”。 - mipe34
谢谢,添加了name属性,现在它可以工作了。 - hncl
我会把它作为答案发布;-) - mipe34
显示剩余2条评论
2个回答

3
您的应用程序中存在空的catch块。这并不是一个好主意,如果您想要更深入地了解此问题,请参见为什么空的catch块是个坏主意?以及相关问题。
您遇到的问题可能如下所述:
  • Sendlink(FormCollection formCollection)方法的try块内部某处抛出了异常。由于该try块内的所有其他调用都没有生成异常(特别是由于您抑制了MailEngine.Send方法抛出的异常),因此此异常似乎起源于RedirectToAction("CanvasShare")调用。
  • 您的Sendlink(FormCollection formCollection)中的空的catch块被调用。这是您应该生成错误消息并向用户显示它的地方。但是,您决定将其留空,因此没有人知道发生了什么以及是什么问题。
  • 控制流程达到您的Sendlink(FormCollection formCollection)方法中的return null;语句。我猜您在其中放置了这个语句,因为编译器抱怨缺少返回值。现在返回null并导致呈现空视图。
显然的解决方法是检查RedirectToAction并找出它为什么会抛出异常。该异常可能表示您的代码或应用程序中存在问题,因此您需要采取措施防止其发生。
下一个修复方法是实际上在您的应用程序中实现错误处理。删除所有空的catch块,并考虑是否要抛出异常或是否要立即处理它。忽略它几乎从来不是一个好主意。
为了说明您应用程序中的问题:如果RedirectToAction中没有抛出异常,则您的电子邮件发送可能仍会失败。但是,由于您在MailClient.Send方法中忽略了异常,因此您的UI无法找出发生了什么错误。如果您将其发布到生产环境中,电子邮件发送将默默地失败,您的客户将想知道为什么他们从未收到电子邮件。那时,您将很难找出实际问题所在以及发生了什么。

非常感谢你,Chris。这对我在我的代码中实现非常有用。 - hncl

2

toemail将始终为null。

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

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

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

在ASP MVC中,处理异常的选项有几种。我最喜欢的方法是将异常过滤器和<CustomErrors mode="On"/> 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
@Chris:当 toemail 为空时,邮件引擎很可能会抛出异常。因此,操作结果为 null -> 空白屏幕。 - mipe34
MailEngine永远不会抛出异常,因为所有的异常都被捕获在MailEngine.Send内部。 - Chris
1
你是对的,我忽略了它。 另一个可能抛出 NullReferenceException 的位置是 string message = Session["link"].ToString(); - mipe34
是的,但这仍然不是通过在“input”标记上添加“name”属性来影响的内容。我想知道为什么会促使行为发生变化。 - Chris
我也是;-) 我不明白为什么RedirectToAction应该抛出异常的原因。所以我看到的最后一个选项是Session中“link”的巧合(未设置)值。如果我能自己调试它,那就容易多了;-) - mipe34

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接