Asp.net mvc ASP.NET MVC-用户输入和服务/存储库-在哪里进行验证?

Asp.net mvc ASP.NET MVC-用户输入和服务/存储库-在哪里进行验证?,asp.net-mvc,design-patterns,Asp.net Mvc,Design Patterns,这可能是一个过于固执己见的问题,但正在寻求帮助 我一直在努力完善我的ASP.NETMVC程序结构。我刚在preview 5中开始使用它,这是我第一次涉足业务应用程序开发——所以一切都是新的 在控制器级别,我有一个服务对象,负责与存储库通信并处理所有业务逻辑。在操作级别,我有一个对象,它保存所有视图数据——用户输入和生成的输出——我将其称为视图对象(有一个通用术语吗?)。与我看到的大多数示例不同,该对象不是数据库对象,而是特定于视图的对象 现在我想添加用户验证。问题是,我不知道该把它放在哪里。对我

这可能是一个过于固执己见的问题,但正在寻求帮助

我一直在努力完善我的ASP.NETMVC程序结构。我刚在preview 5中开始使用它,这是我第一次涉足业务应用程序开发——所以一切都是新的

在控制器级别,我有一个服务对象,负责与存储库通信并处理所有业务逻辑。在操作级别,我有一个对象,它保存所有视图数据——用户输入和生成的输出——我将其称为视图对象(有一个通用术语吗?)。与我看到的大多数示例不同,该对象不是数据库对象,而是特定于视图的对象

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

因此,我看到的一些选择是:

  • 对传递给方法的参数在Service.Method中进行验证
  • 在调用Service.Method之前,在视图对象中执行验证
  • 在视图对象中执行验证,但使服务。方法需要一个视图对象引用,因此它在对象上启动验证

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

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

看看S#arp体系结构项目。对模型进行验证,以确保没有实体以无效状态持久化到数据库。它通过使用NHibernate.Validator并将其附加到NHibernate的保存和更新事件来实现这一点


就我个人而言,这种方法对我来说最有意义,因为您不必在多个控制器中重复验证逻辑。

查看以下博客文章


这上面有一些有趣的链接

就我个人而言,我已经将验证添加到我的服务层对象(前两个链接)。这样,如果任何控制器中的任何方法决定调用我的服务方法。。逻辑全部检查并装箱在一个位置。干的

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

最后,当前的MVC dll能够将错误消息传递回UI。。因此视图可以很好地显示它们。退房:-

  • ViewData.ModelState.AddModelError(键,消息)

我担心我的帖子不会得到回复,很高兴我错了

我以前读过这些链接,但可能是一个多月前,用我现在了解的内容重新阅读它们非常有帮助。我真的很喜欢史蒂夫·桑德森(Steve Sanderson)关于滑动比例的帖子,但我希望他能展示一个在正确的角度验证某些东西的例子

他在博客中举了一个例子:“‘用户名必须是唯一的’可能会在数据库中强制执行”。那么这会是这样的:

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,但没有坐下来看看它是如何工作的(我不确定它是否有很多演示,或者下载代码就是演示!)。我不确定仅仅对数据库模型进行验证是否足够。在我看来,对于业务逻辑会说无效的数据库,会有很多有效的模型状态(例如日期范围/必须在/之前/之后/等等)。这些案例让我绞尽脑汁:)

还有一个我喜欢的链接(在我看到Emad用BLL回复Steves的帖子后在Google上搜索了一下,不知道这是什么意思……嗯):

所以我不知道,但我认为这就是我要写的模型:处理数据交互的业务流程对象,以及作为逻辑模型而不是数据库模型的业务实体。我想我需要开始阅读一些更基本的模式和实践,以便更好地理解这些概念(看起来很多都是Java人编写的,而不是NET人编写的)
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
  }
}
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
  }
}