我正在构建一个ASP.NET MVC项目,并采用以下架构:
所以,假设我想添加一个用户。我在核心项目中定义了NewUserInputModel
。我给它一些数据注释,例如[Required]
。完成此操作后, Web 项目将根据这些注释执行客户端验证。
我的问题是关于服务器端验证。我想使用客户端使用的相同规则验证NewUserInputModel
,并且我希望运行NewUserInputModel
来自 API 的验证天气或 Web 项目。
我意识到我可以从 Web 项目中的Controller调用ModelState.IsValid
- 但我想从 Core 项目调用该验证,以便所有验证逻辑生活在核心中。这样,无论这个模型如何进入核心逻辑,我总是调用相同的验证。我不想将System.Web
引用泄露到我的 Core 项目中。
这是一个合理的设计吗?我认为是 - 但如果有什么东西闻起来,我会很高兴听到它。
提前感谢您的帮助。
答案 0 :(得分:15)
我认为你的方法很好。将一组模型映射到另一组模型可能会带来一些错误。
您正在寻找的代码是:
using System.ComponentModel.DataAnnotations;
var context = new ValidationContext(model, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(model, context, results);
if (!isValid)
throw new Exception("Model is not valid because " + string.Join(", ", results.Select( s => s.ErrorMessage).ToArray()));
有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationcontext.aspx或http://odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx
答案 1 :(得分:3)
我通常将我的视图模型保存在Web项目中,并使用ModelState
属性在控制器中执行输入验证。如果成功,我将它们映射到域模型(它们位于Core层)并将它们发送到服务(也可能是Core)层中的服务。服务层验证业务规则,如果成功,则调用存储库执行所需操作,并将操作结果返回给控制器。
在Web项目中保留视图模型还允许您使用MVC验证属性,例如RemoteAttribute
。
我不是说您的设计闻起来,但我认为将表示逻辑与Core层分开是好的。
答案 2 :(得分:0)
我通过快速思考来解决这个问题的方法就是做那样的事情。在业务层创建
public class ValidationMessage
{
public ValidationMessage(string message, ValidationMessageType messageType)
{
Message = message;
MessageType = messageType;
}
public string Message { get; private set; }
public ValidationMessageType MessageType { get; private set; }
}
public enum ValidationMessageType
{
Info,
Warning,
Error,
}
现在有一个服务示例
public interface ISomeService
{
List<ValidationMessage> Edit(SomeModel item);
}
现在在控制器中调用服务并将验证消息传递给视图。可能需要使用ViewBag并传递整个列表。在视图上,您可以突出显示信息,警告,错误。例如,您可以使用Info类型返回一些成功消息,或者根本不返回控制器创建成功消息。
通常这种方法更多编码,但更灵活。理想情况下,服务会验证所有内容,但对于较小的项目来避免验证重复,正如Henk Mollema在他的回答中所述,您可以通过ViewModel进行用户输入验证,并且在服务中只验证关键业务规则。
ValidationMessageType也可能是一种过度杀伤,因此可以从服务中返回List作为错误列表,空列表就意味着成功。
答案 3 :(得分:0)
进行混合验证也很有用,因此将DataAnnotations与自定义验证逻辑混合
这可能会有所帮助 http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2