在 ASP.NET MVC C# 中验证表单
Validating Form in ASP.NET MVC C#
所以正如标题所说,我正在尽一切努力让这个验证工作,使用 RegEx 和所有,但它就是行不通。我在这里做错了什么?
您根本不需要在表单中键入任何数据,您仍然可以发送空邮件,我不希望那样...
型号:
using System.ComponentModel.DataAnnotations;
namespace DK_Design.Models
{
public class SendMail
{
[Required]
public string Name { get; set; }
[Required]
public string Email { get; set; }
public string Number { get; set; }
[Required]
public string Message { get; set; }
}
}
查看:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
<div class="row">
<div class="box">
<div class="col-lg-12">
<hr>
<h2 class="intro-text text-center">
Kontakta
<strong>Oss!</strong>
</h2>
<hr>
</div>
<div class="col-md-8">
</div>
<div class="col-md-4">
<p>
Telefon:
<strong>123.456.7890</strong>
</p>
<p>
Email:
<strong><a href="mailto:*****@live.se">*****@live.se</a><!--I am obviously blurring the email on purpose here. The email function itself works.--> </strong>
</p>
<p>
Address:
<strong>
3481 Melrose Place
<br>Beverly Hills, CA 90210
</strong>
</p>
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div class="box">
<div class="col-lg-12">
<hr>
<h2 class="intro-text text-center">
Skicka
<strong>Ett Meddelande</strong>
</h2>
<hr>
@if (ViewData["Message"] != null)
{
<div class="alert alert-success">Ditt e-mail har skickats!</div>
}
@if (ViewData["Message"] == null)
{
<div class="alert alert-danger">Ditt e-mail kan inte skickas!</div>
}
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat, vitae, distinctio, possimus repudiandae cupiditate ipsum excepturi dicta neque eaque voluptates tempora veniam esse earum sapiente optio deleniti consequuntur eos voluptatem.</p>
<form class="form-wrapper" id="contact-form" method="post" role="form" novalidate>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-4">
<label for="name">
Namn *
</label>
<input type="text" id="name" name="name" class="form-control" data-errmsg="Name is required."
placeholder="Ditt Namn" required />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-4">
<label for="email">
Email *
</label>
<input type="text" id="email" name="email" class="form-control" data-errmsg="Email is required."
placeholder="Ditt Email" required />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-4">
<label for="number">
Telefonnummer
</label>
<input type="text" id="number" name="number" class="form-control"
placeholder="Ditt Telefonnummer" />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-8">
<label for="message">
Meddelande *
</label>
<textarea id="message" name="message" class="form-control" data-errmsg="Message is required."
placeholder="Ditt Meddelande" rows="3" required></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-2 col-sm-2 offset2">
<input style="font-size: 20px" type="submit" id="sendMail" value="Skicka" class="btn btn-primary" />
</div>
</div>
</form>
</div>
</div>
</div>
</div>
控制器:
using DK_Design.Models;
using System.Net.Mail;
using System.Web.Mvc;
namespace DK_Design.Controllers
{
public class KontaktController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(SendMail input)
{
var mail = new MailMessage("*****", "*****");
var client = new SmtpClient("smtp-mail.outlook.com");
client.Port = 587;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
var credentials = new System.Net.NetworkCredential("*****", "*****");
client.EnableSsl = true;
client.Credentials = credentials;
mail.Body = input.Name + " " + input.Email + " " + input.Number + " " + input.Message;
mail.Subject = "Paket 1";
client.Send(mail);
ViewData["Message"] = mail;
return View(mail);
//Blurring the email information here too ofcourse.
}
}
}
我在发送电子邮件时弹出成功消息,但反之则不然。
您的视图模型装饰有必需的数据注释。所以你可以使用内置的模型验证。
[HttpPost]
public ActionResult Index(SendMail input)
{
if(!ModelState.IsValid)
return View(input);
//Your existing code here which sends email
}
确保您拥有在视图中显示通知消息的相关代码。您可以根据需要使用 ValidationSummary or/and ValidationFor 辅助方法。您也可以使用 html 辅助方法来呈现输入字段。助手将生成显示验证错误消息所需的标记。
@model SendMail
@using(Html.BeginForm())
{
@Html.LabelFor(s=>s.Name)
@Html.TextBoxFor(s=>s.Name)
@Html.ValidationMessageFor(t => t.Name)
@Html.LabelFor(s=>s.Email)
@Html.TextBoxFor(s=>s.Email)
@Html.ValidationMessageFor(t => t.Email)
@Html.LabelFor(s=>s.Number)
@Html.TextBoxFor(s=>s.Number)
@Html.ValidationMessageFor(t => t.Number)
@Html.LabelFor(s=>s.Message)
@Html.TextAreaFor(s=>s.Message)
@Html.ValidationMessageFor(t => t.Message)
<input type="submit" />
}
我还建议您遵循 PRG 模式 (Post-Redirect-GET)。因此,您不会返回到相同的视图,而是重定向到另一个 GET 操作。
return RedirectToAction("EmailSent");
要使用客户端验证 (jquery val),您应该考虑使用内置函数
@Html.TextBoxFor(m => m.Name)
其他属性也类似。
如果表单为空,这将阻止用户提交表单
然后在服务器端你想做
if(!ModelState.IsValid)
return View(input);
阻止服务器发送无效的电子邮件
正如几个人所说,由于您正在使用数据注释(视图模型中的 [Required] 标记),好消息是您不必添加太多内容即可解决问题。
要防止它发送空白电子邮件,请将以下内容添加到您的控制器:
if(!ModelState.IsValid)
{
throw some kind of error here or do something else and return
}
仅当传入数据不为空时,ModelState 才有效,这将阻止访问其余代码(并发送电子邮件)。有一个关于 ModelState 的教程 here 值得一读。本教程还讨论了添加自定义验证器,如果您需要在提供的 MVC 数据注释之外进行验证,您可能会发现它很有用。
我会推荐验证消息和检查,以便在用户输入信息时为他们提供反馈。可以按照添加 [Required] 标签的相同方式将它们添加到您的模型中:
[Required]
[StringLength(8, ErrorMessage = "The input cannot be longer than 8 characters.")]
public string StringyThingie { get; set; }
您还可以在此处添加正则表达式(因为您已经提到使用它)以及验证消息:
[Required]
[RegularExpression(@"^\d{0,4}+.\d{0,8}$", ErrorMessage = "Entry must be in the form of a decimal with no more than eight places to the right of the period.")]
public Decimal DecimalThingie { get; set; }
附带说明一下,如果您想在使用正则表达式之前检查它的有效性,Visual Studio 有几个可以通过 Nuget 获取的内置工具。
您可以将验证 check/message 直接添加到您的视图中,在用户输入的表单组中:
<div class="form-group">
@Html.LabelFor(model => model.Field, htmlAttributes: new { @class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.Field, new { htmlAttributes = new { @class = "form-control"}}
@Html.ValidationMessageFor(model => model.Field, "", new { @class = "text-danger"})
</div>
</div>
html 助手 ValidationMessageFor 将查看您的模型并获取您列出的要验证的消息,并在用户尝试 post 页面时显示它。连同模型变量上的其他数据注释和 ModelState 检查,它将阻止用户继续前进,直到字段具有满足您检查的内容,并阻止控制器方法的其余部分在 null 过去的情况下执行你的支票。
您还需要将以下内容添加到您的视图中,以提供验证失败的摘要(您应该自定义其中的参数):
@Html.ValidationSummary(true, "", new { @class = "text-danger"})
您不希望 return 方法末尾的视图——您应该使用 RedirectToAction 方法:
return RedirectToAction("YourMethodHere", "YourControllerHere", "YourRouteDataHere");
RedirectToAction 命令明确强制通过视图控制器执行。
数据注释非常灵活,与尝试自己对传入数据编写所有这些检查相比,使用它们可以使您编写的代码相对较少。该文档可在 MSDN 文档中找到,并内置于 MVC 系统中。
为了更好地控制它在 MVC 系统内部错误(不是 Html 错误)的错误过程中所做的事情,您可以重写 MVC 方法 OnException,但这会使您的编码过程相当复杂。 here.
可以找到关于如何以及为什么的很好的教程
但是,我对这个问题的建议是利用 Elmah 包,而不是尝试自己编写。可以使用以下命令通过内置的 Nuget 包管理器获取 Elmah:
PM> Install-Package Elmah.MVC
安装它可以更轻松地记录和管理错误,并允许对该过程进行大量自定义,而无需自行管理过滤器和路由。
所以正如标题所说,我正在尽一切努力让这个验证工作,使用 RegEx 和所有,但它就是行不通。我在这里做错了什么?
您根本不需要在表单中键入任何数据,您仍然可以发送空邮件,我不希望那样...
型号:
using System.ComponentModel.DataAnnotations;
namespace DK_Design.Models
{
public class SendMail
{
[Required]
public string Name { get; set; }
[Required]
public string Email { get; set; }
public string Number { get; set; }
[Required]
public string Message { get; set; }
}
}
查看:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
<div class="row">
<div class="box">
<div class="col-lg-12">
<hr>
<h2 class="intro-text text-center">
Kontakta
<strong>Oss!</strong>
</h2>
<hr>
</div>
<div class="col-md-8">
</div>
<div class="col-md-4">
<p>
Telefon:
<strong>123.456.7890</strong>
</p>
<p>
Email:
<strong><a href="mailto:*****@live.se">*****@live.se</a><!--I am obviously blurring the email on purpose here. The email function itself works.--> </strong>
</p>
<p>
Address:
<strong>
3481 Melrose Place
<br>Beverly Hills, CA 90210
</strong>
</p>
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div class="box">
<div class="col-lg-12">
<hr>
<h2 class="intro-text text-center">
Skicka
<strong>Ett Meddelande</strong>
</h2>
<hr>
@if (ViewData["Message"] != null)
{
<div class="alert alert-success">Ditt e-mail har skickats!</div>
}
@if (ViewData["Message"] == null)
{
<div class="alert alert-danger">Ditt e-mail kan inte skickas!</div>
}
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat, vitae, distinctio, possimus repudiandae cupiditate ipsum excepturi dicta neque eaque voluptates tempora veniam esse earum sapiente optio deleniti consequuntur eos voluptatem.</p>
<form class="form-wrapper" id="contact-form" method="post" role="form" novalidate>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-4">
<label for="name">
Namn *
</label>
<input type="text" id="name" name="name" class="form-control" data-errmsg="Name is required."
placeholder="Ditt Namn" required />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-4">
<label for="email">
Email *
</label>
<input type="text" id="email" name="email" class="form-control" data-errmsg="Email is required."
placeholder="Ditt Email" required />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-4">
<label for="number">
Telefonnummer
</label>
<input type="text" id="number" name="number" class="form-control"
placeholder="Ditt Telefonnummer" />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="form-group col-lg-8">
<label for="message">
Meddelande *
</label>
<textarea id="message" name="message" class="form-control" data-errmsg="Message is required."
placeholder="Ditt Meddelande" rows="3" required></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-2 col-sm-2 offset2">
<input style="font-size: 20px" type="submit" id="sendMail" value="Skicka" class="btn btn-primary" />
</div>
</div>
</form>
</div>
</div>
</div>
</div>
控制器:
using DK_Design.Models;
using System.Net.Mail;
using System.Web.Mvc;
namespace DK_Design.Controllers
{
public class KontaktController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(SendMail input)
{
var mail = new MailMessage("*****", "*****");
var client = new SmtpClient("smtp-mail.outlook.com");
client.Port = 587;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
var credentials = new System.Net.NetworkCredential("*****", "*****");
client.EnableSsl = true;
client.Credentials = credentials;
mail.Body = input.Name + " " + input.Email + " " + input.Number + " " + input.Message;
mail.Subject = "Paket 1";
client.Send(mail);
ViewData["Message"] = mail;
return View(mail);
//Blurring the email information here too ofcourse.
}
}
}
我在发送电子邮件时弹出成功消息,但反之则不然。
您的视图模型装饰有必需的数据注释。所以你可以使用内置的模型验证。
[HttpPost]
public ActionResult Index(SendMail input)
{
if(!ModelState.IsValid)
return View(input);
//Your existing code here which sends email
}
确保您拥有在视图中显示通知消息的相关代码。您可以根据需要使用 ValidationSummary or/and ValidationFor 辅助方法。您也可以使用 html 辅助方法来呈现输入字段。助手将生成显示验证错误消息所需的标记。
@model SendMail
@using(Html.BeginForm())
{
@Html.LabelFor(s=>s.Name)
@Html.TextBoxFor(s=>s.Name)
@Html.ValidationMessageFor(t => t.Name)
@Html.LabelFor(s=>s.Email)
@Html.TextBoxFor(s=>s.Email)
@Html.ValidationMessageFor(t => t.Email)
@Html.LabelFor(s=>s.Number)
@Html.TextBoxFor(s=>s.Number)
@Html.ValidationMessageFor(t => t.Number)
@Html.LabelFor(s=>s.Message)
@Html.TextAreaFor(s=>s.Message)
@Html.ValidationMessageFor(t => t.Message)
<input type="submit" />
}
我还建议您遵循 PRG 模式 (Post-Redirect-GET)。因此,您不会返回到相同的视图,而是重定向到另一个 GET 操作。
return RedirectToAction("EmailSent");
要使用客户端验证 (jquery val),您应该考虑使用内置函数
@Html.TextBoxFor(m => m.Name)
其他属性也类似。
如果表单为空,这将阻止用户提交表单
然后在服务器端你想做
if(!ModelState.IsValid)
return View(input);
阻止服务器发送无效的电子邮件
正如几个人所说,由于您正在使用数据注释(视图模型中的 [Required] 标记),好消息是您不必添加太多内容即可解决问题。
要防止它发送空白电子邮件,请将以下内容添加到您的控制器:
if(!ModelState.IsValid)
{
throw some kind of error here or do something else and return
}
仅当传入数据不为空时,ModelState 才有效,这将阻止访问其余代码(并发送电子邮件)。有一个关于 ModelState 的教程 here 值得一读。本教程还讨论了添加自定义验证器,如果您需要在提供的 MVC 数据注释之外进行验证,您可能会发现它很有用。
我会推荐验证消息和检查,以便在用户输入信息时为他们提供反馈。可以按照添加 [Required] 标签的相同方式将它们添加到您的模型中:
[Required]
[StringLength(8, ErrorMessage = "The input cannot be longer than 8 characters.")]
public string StringyThingie { get; set; }
您还可以在此处添加正则表达式(因为您已经提到使用它)以及验证消息:
[Required]
[RegularExpression(@"^\d{0,4}+.\d{0,8}$", ErrorMessage = "Entry must be in the form of a decimal with no more than eight places to the right of the period.")]
public Decimal DecimalThingie { get; set; }
附带说明一下,如果您想在使用正则表达式之前检查它的有效性,Visual Studio 有几个可以通过 Nuget 获取的内置工具。
您可以将验证 check/message 直接添加到您的视图中,在用户输入的表单组中:
<div class="form-group">
@Html.LabelFor(model => model.Field, htmlAttributes: new { @class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.Field, new { htmlAttributes = new { @class = "form-control"}}
@Html.ValidationMessageFor(model => model.Field, "", new { @class = "text-danger"})
</div>
</div>
html 助手 ValidationMessageFor 将查看您的模型并获取您列出的要验证的消息,并在用户尝试 post 页面时显示它。连同模型变量上的其他数据注释和 ModelState 检查,它将阻止用户继续前进,直到字段具有满足您检查的内容,并阻止控制器方法的其余部分在 null 过去的情况下执行你的支票。
您还需要将以下内容添加到您的视图中,以提供验证失败的摘要(您应该自定义其中的参数):
@Html.ValidationSummary(true, "", new { @class = "text-danger"})
您不希望 return 方法末尾的视图——您应该使用 RedirectToAction 方法:
return RedirectToAction("YourMethodHere", "YourControllerHere", "YourRouteDataHere");
RedirectToAction 命令明确强制通过视图控制器执行。
数据注释非常灵活,与尝试自己对传入数据编写所有这些检查相比,使用它们可以使您编写的代码相对较少。该文档可在 MSDN 文档中找到,并内置于 MVC 系统中。
为了更好地控制它在 MVC 系统内部错误(不是 Html 错误)的错误过程中所做的事情,您可以重写 MVC 方法 OnException,但这会使您的编码过程相当复杂。 here.
可以找到关于如何以及为什么的很好的教程但是,我对这个问题的建议是利用 Elmah 包,而不是尝试自己编写。可以使用以下命令通过内置的 Nuget 包管理器获取 Elmah:
PM> Install-Package Elmah.MVC
安装它可以更轻松地记录和管理错误,并允许对该过程进行大量自定义,而无需自行管理过滤器和路由。