ASP.NET MVC - 用户输入和服务/存储库 - 在哪里做验证?

ASP.NET MVC - 用户输入和服务/存储库 - 在哪里做验证?

问题描述:

这可能太想了一个问题,但寻求帮助!ASP.NET MVC - 用户输入和服务/存储库 - 在哪里做验证?

我一直在努力改进我的ASP.NET MVC程序结构。我刚开始在预览版5上使用它,这是我第一次进入商业应用程序开发 - 所以每一个都是新的!

在控制器级别,我有责任与版本库,并采取所有的业务逻辑的护理服务对象。在动作级别,我有一个保存所有视图数据的对象 - 用户输入和生成的输出 - 我将调用视图对象(这是否有一个通用术语?)。与我看到的大多数示例不同,此对象不是数据库对象,而是特定于视图的对象。

所以现在我要添加用户验证。问题是,我不知道该把它放在哪里。对我来说,最重要的是在服务层中完成它。服务层负责所有业务逻辑,验证是业务逻辑。另一方面,我所看到的大多数验证框架都用于验证对象,这让我认为视图对象应该是验证意识。最后,还有一些需要数据库连接的验证方法(例如检查用户输入字段是否具有相应的数据库记录),并且视图对象没有数据库的概念,只有服务。

所以一些选项我看到的是:

  • 验证是否在传递到方法的参数Service.Method。
  • 在调用Service.Method之前在视图对象中进行验证。
  • 在视图对象中进行验证,但是使Service.Method需要一个视图对象引用,以便它启动对该对象的验证。

我敢肯定有更多。我很好奇其他人如何处理MVC意义上的用户输入验证。我以前使用过企业验证块,并且喜欢能够使用股票验证器来处理所有事情,但我不确定如何使它适合单独的视图对象和服务层。如果他们(视图对象/服务)是同一个对象,这也许是人们做的事情,那将是容易的事情?就像我说的,它对我来说都是新的,我正在寻找最佳实践/模式。

我通常做的时候提交表单的控制器动作基本验证(必填字段,电子邮件格式等)。然后,我让业务层处理需要业务知识的验证。我通常会仔细检查业务层中的基本内容,因此如果我通过Web服务公开该逻辑或稍后在其他应用程序中使用该逻辑,那么我仍然会验证其最重要的地方(IMO)。

看看S#arp Architecture项目。验证在模型上进行处理,以确保没有实体以无效状态持久保存到数据库。它通过使用NHibernate.Validator并将其附加到NHibernate的保存和更新事件来完成。

就个人而言,这种做法是很有道理的我,因为你没有复制在多个控制器的验证逻辑。

有这个

就我个人而言,我已向我的服务层对象(前两个链接)添加了验证。这样,如果任何方法在任何控制器决定调用我的服务方法..逻辑都在一个位置检查和装箱。 DRY

这就是说,我也有一些UI验证(第三链接)..以减少往返时间。

最后,当前的MVC DLL有能力将错误消息传递回UI ..所以视图可以很好地显示它们。退房: -

  • ViewData.ModelState.AddModelError(密钥,消息)

心连心!

我怕我的帖子没有回复,很高兴错了!

我已经阅读过这些链接,但可能在一个月或更久之前,重新阅读我现在了解的内容对我非常有帮助。我真的很喜欢史蒂夫桑德森的职位,但希望他能展示一个证明右边的东西的例子。

作为他博客中的一个示例,他给出了:“'用户名必须是唯一的'可能会在您的数据库中强制执行”。因此,这会不会是这样的:

public static void SavePerson(Person person) 
{ 
    // make sure it meets some format requirement 
    // in this case the object is responsible for validation and the service layer is the caller 
    person.EnsureValid(); 

    // todo: action to verify username is unique by checking database 
    // in this case the service layer is responsible for calling and implementing validation 

    // todo: action to save to database 
} 

这是有道理的,并且能显示出我的麻烦抓往哪里放审定它既是服务层(非常独特的名字)和视图对象(验证格式)内。

我的另一个问题是服务层开始带验证逻辑。也许把它分成不同的班级或别的什么?在我的情况下,一些验证逻辑可能会在服务之间共享,所以我想想一个干的方法来实现这一点。有趣的东西想想!

Emad Ibrahim的链接很棒,因为一旦我开始理解这个过程,我将寻找一种方法来使用相同的一组规则生成javascript客户端验证,而无需重复代码。他已经有了:)

我听说过S#arp,但没有坐下来,看到它是如何工作的(我不确定是否有很多演示的方式,或者如果下载代码是演示!)。我不确定是否仅对数据库模型进行验证就足够了。在我看来,对于业务逻辑所说的无效数据库(比如日期范围/必须在/之前/之后),会有很多有效的模型状态。这些都是那些令人头大我的大脑:)

同样的情况下,链接我喜欢(GOOGLE了它后,我看到了伊马德答复史蒂夫发布与BLL和不知道是什么意思......杜):

http://en.wikipedia.org/wiki/Business_logic_layer

所以我不知道它,但我认为这是我正在写的模型:处理数据交互的Business Process对象,以及逻辑模型而非数据库模型的业务实体。我想我需要开始阅读一些更基本的模式和实践,以更好地理解这些概念(看起来很多这是Java人写的东西与.NET人的东西)。它可能是时候退一步:)

我在最近的项目中遇到过这个相同的问题。首先,为了重申问题,我试图遵循以域为中心的DDD方法。我将实体组合成可以验证自己的聚合体,并且存储库在保存时验证有效性。 UI还可以从聚合中获取有效性信息,以向客户显示错误反馈。一般的方法是尽可能地利用ASP.NET MVC的模型绑定和验证/表单UI帮助器。这创建了简单的UI流程:1)绑定,2)验证,3)如果有效,保存,否则重新填充视图。

但是,如何在涉及DDD服务的情况下如何充分利用ASP.NET MVC和这种简单的流程并不直接。本来,我发展我的服务,例如:

public class SomeProcessService 
{ 
    public Result Execute(int anAggregateID, int anotherAggregateID, string someData) 
    { 
    // validate input 

    // if invalid, return failures 

    // else 
    // modify aggregates 
    // using (transaction) 
    // { 
    //  save aggregates 
    //  commit 
    // } 

    // return success 
    } 
} 

的问题是,验证和保存的方法是密不可分的。为了利用MVC模型绑定,我们需要一些可以作为绑定模型的东西。我重构此:

public class SomeProcessService 
{ 
    public class Request : IValidateable 
    { 
    public int AggregateID {get;set;} 
    public int AnotherAggregateID {get;set;} 
    public string SomeData {get;set;} 

    public Result Validate() 
    { 
     // validation 
    } 
    } 

    public void Execute(Request request) 
    { 
    // validate input by calling request.Validate() 

    // if invalid, throw new ValidationException(request) 

    // else 
    // modify aggregates 
    // using (transaction) 
    // { 
    //  save aggregates 
    //  commit 
    // } 

    // return success 
    } 
} 

这repurposes的Parameter Object pattern到单独的方法输入验证。我可以绑定到我的控制器中的SomeProcessService.Request对象,并在那里获取验证信息。如果一切正常,则从我的控制器使用Request对象作为参数发起服务调用。这种方法似乎很高兴将DDD服务与ASP.NET MVC验证要求结合在一起。