ASP.NET MVC:使用相同的服务验证和处理模型

时间:2011-03-26 10:15:50

标签: c# .net asp.net-mvc validation

在阅读有关使用服务层进行验证的this文章后,我有些疑惑。

第一:如文章所示,将整个模型视图传递给服务是否可以?我已经看到一些例子,而不是传递控制器使用的整个模型(如bool success = _productService.CreateProduct(productModel)),他们称这样的服务:

 bool success = _productService.CreateProduct(productModel.Name, productModel.Category, productModel.Cost)

两种方法的优点/缺点是什么?

第二:我可以看到使用相同服务验证模型和完成实际工作的逻辑。另一方面,这意味着该服务必须处理两个问题:数据验证和数据处理。这意味着同一服务中的代码更多,可测试性更差,对吧?

因此,不是上面的示例代码,最好是:

bool valid = _productValidationService(productModel);
if(valid){
    _productService.CreateProduct(productModel);
    //or maybe _productService.CreateProduct(productModel.Name, productModel.Category, productModel.Cost);
}

有哪些优点/缺点?有没有我看不到的东西?你用什么 ?什么是标准方法?

1 个答案:

答案 0 :(得分:1)

我更喜欢将整个模型传递给服务而不是单个属性,以避免使方法混乱。就验证逻辑而言,你说它必须处理两个问题:业务逻辑验证和实际保存。我认为这两个问题属于该服务。此服务的使用者不应该只能在不首先验证的情况下调用save,并且在服务中执行这两项操作可确保不会发生这种情况。此外,实际保存可以由服务方法委派给一个或多个CRUD存储库调用。

所以在控制器中:

string error;
if (!_productService.TryCreateProduct(productModel, out error))
{
    ModelState.AddModelError("key", error);
    return View(viewModel);
}

在您链接的文章中,以下方法用于初始化服务并将其传递给模型状态,以便直接写入错误:

_productService = new ProductService(
    _productRepository, 
    new ModelStateValidationWrapper(this.ModelState)
);

以后你可以直接:

_productService.CreateProduct(productModel);

这也是一种有效且好的方法。唯一的问题是控制器内部的以下行_productService = new ProductService(...非常糟糕,因为它将控制器与服务的特定实现紧密耦合。该服务应该由DI框架注入,但问题是传递ModelState,因为它会创建循环依赖。这里有some threads来解决这个问题。