我正在一个网站上工作,只是试图了解一般结构。我在后台有一个数据库,我正在使用“存储库模式”访问。我在 UserRepository 类中有以下代码:
public bool IsValid(User user)
{
if (_context.Users.Any(c => c.EmailAddress == user.EmailAddress))
{
Message = "Email address already in use";
return false;
}
return true;
}
这是在这里实施的
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(User user)
{
if (ModelState.IsValid)
{
var context = new Context("DatabaseContext");
var userRepo = new UserRepository(context);
if (userRepo.IsValid(user))
{
userRepo.Add(user);
// return to different view
}
else
{
// display userRepo.Message on page
return View(user);
}
}
return View(user);
}
我的问题是我不认为我正确地绕过“消息”位,但我找不到任何在线帮助我(特别是在存储库周围)。我认为我应该将 IsValid 的返回类型更改为结果(就像我在对话框中看到的那样),但同样,我不确定。
非常感谢任何帮助。
感谢。
答案 0 :(得分:2)
实现此目的的一种方法与您建议的完全一样 - 更改IsValid
的返回类型。
过去我在“业务层”中有类似的验证方法,它返回ValidationResult
的集合,其中每个返回的记录都会在模型中解释验证错误,而空集合将被解释为有效的模型。
例如:
public class ValidationResult
{
public string FieldName { get; set; }
public string Message { get; set; }
}
public interface IValidator<T>
{
IEnumerable<ValidationResult> IsValid(T model);
}
//...in your implementation
public IEnumerable<ValidationResult> IsValid(User user)
{
//Return a new ValidationResult per validation error
if (_context.Users.Any(c => c.EmailAddress == user.EmailAddress))
{
yield return new ValidationResult
{
Message = "Email address already in use",
FieldName = nameof(user.EmailAddress)
};
}
}
然后,您的表示层可以将其解释为反馈给用户。
答案 1 :(得分:2)
我同意你提到的问题。返回自定义类将更好地接近IMO。
public ValidationResult IsValid(User user)
{
ValidationResult validationResult = new ValidationResult(true, "");
if (_context.Users.Any(c => c.EmailAddress == user.EmailAddress))
{
validationResult.Status = false;
validationResult.Message = "Email address already in use";
return validationResult;
}
return validationResult;
}
这样,Status
和Message
会为您提供所需的所有信息。首先检查状态。如果为false,请检查消息以获取确切的详细信息。
答案 2 :(得分:1)
虽然上述用户提供的解决方案很好,但我不认为你这样做是正确的。这种验证电子邮件地址解决方案有一些缺点。
假设如果电子邮件可用(无效,因为这不是有效性),那么您必须返回错误视图。如果所有输入电子邮件地址都可用,那么最终用户将多次获得此错误但整个视图将在每个请求中呈现,这不是一个好的做法。总是尝试在这种情况下使用远程验证。
在您的模型属性(电子邮件)上使用Remoteattribute
,并尝试通过JsonResult
动态返回可用性消息。我将为您提供此演示示例,您可以随意在代码中实现。
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public JsonResult IsEmailAvailable(string emailAddress)
{
if (!_context.Users.Any(c => c.EmailAddress == emailAddress))
{
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json("Email address already taken" , JsonRequestBehavior.AllowGet);
}
为了防止ASP.NET MVC缓存验证方法的结果,需要OutputCacheAttribute
属性。
装饰您的模型电子邮件属性,如下所示:
//inside you model.
[Required]
[Remote("IsEmailAvailable", "YourControllerName")]
[RegularExpression(@"Your email address validation regex here", ErrorMessage = "Email address is not valid .")]
[Editable(true)]
public string Email{ get; set; }
并在Web.config文件中添加此代码段以允许使用Remote属性:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
从register
操作方法中删除以下代码。
if (userRepo.IsValid(user))
{
userRepo.Add(user); //write this only inside code cause you will always get valid email now.
// return to different view
}
else
{
// display userRepo.Message on page
return View(user);
}
我希望这会奏效。有关更多信息,请阅读本文。 https://msdn.microsoft.com/en-us/library/gg508808(vs.98).aspx