0

我问这个,因为很长一段时间后,搜索我还没有找到一个很好的答案对这个尚未...业务/服务层ASP.NET复杂的验证

下面是我想:

例如:我有一个域模型“JobPosting”,如果用户仍然是草稿,那么用户应该可以将状态更改为发布状态。在发布之前,我不仅要验证模型属性,还必须验证有关用户帐户的许多不同要求,它是已注册的公司等。所有此验证逻辑都将放入服务层。到目前为止好...

这是我的业务层看起来像:

public IValidationResult ValidatePublish(JobPosting jobPosting){ 
    ... 
} 

public void Publish(JobPosting jobPosting){ 
    jobPosting.State = JobPostingState.Published; 
    ... 
} 

我的任何控制器:

public ActionResult Publish(PublishViewModel model){ 
    ... 
    var validationResult = _jobService.ValidatePublish(jobPosting); 
    if(validationResult.Success){ 
     _jobService.Publish(jobPosting); 
     ... 
    } 
    ... 
} 

在这里,现在我的问题:

我想能够从控制器调用ValidatePublish在视图中显示验证错误。但是,如果验证失败,我绝不能发布一份工作。 所以有我的代码更健壮,我添加在服务层在我发布方法的第二验证检查:

public void Publish(JobPosting jobPosting){ 
    if(ValidatePublish(jobPosting).Success){ 
     jobPosting.State = JobPostingState.Published; 
     ... 
    } 
} 

,但我还没有这么好的感觉用这种方法,因为我现在在验证调用验证两次在每个控制器发布请求期间都可以。

您怎么看。第二个电话是多少?有更好的方法吗? 我在问,因为我的整个应用程序看起来像这样,如果我永远不会忘记控制器中的验证调用,我可能会在数据库中导致一个不允许的域模型状态。这就是为什么我在每个服务方法中添加第二个验证检查的原因。

在此先感谢您的想法!

+0

“我要求验证两次”第二次你在哪里调用验证? –

+0

控制器中的第一个呼叫: var validationResult = _jobService.ValidatePublish(jobPosting); 第二次服务方法发布: if(ValidatePublish(jobPosting).Success){ – Simon

+0

那么为什么你要在方法中再次验证?你可以直接发布。 –

回答

1

一个快速解决方案可能是让Publisher类需要JobPostingIValidationResult对象作为参数。

public void Publish(JobPosting jobPosting, IValidationResult validation) 
{ 
    if (validation.IsValid) 
    { 
     jobPosting.State = JobPostingState.Published; 
     // other work here... 
    } 
} 

Controller可以调用的Validator,收到IValidationResult,如果需要传递回表示层。否则,传递到Publisher

public ActionResult Publish(PublishViewModel model) 
{ 
    var validationResult = _jobService.ValidatePublish(jobPosting); 
    if(validationResult.Success) _jobService.Publish(jobPosting, validationResult); 
    else return View("error", validationResult); 
} 

编辑:

一个清洁的解决方案可能是有Publisher类返回PublishAttempt结果。

public class PublishAttempt : IValidationResult 
{ 
    public enum AttemptOutcome {get; set;} 
} 

public ActionResult Publish(PublishViewModel model) 
{ 
    var attempt = _jobService.Publish(jobPosting); 
    if (attempt.Success) return View("success"); 
    else return View("error", attempt.ValidationResults); 
} 
+0

谢谢!是的,这也是一种方法......但我不喜欢的是,我可以通过任何验证结果实例......甚至可以创建一个总是有效的新空白实例。 – Simon

+0

噢,谢谢:-)是的,我喜欢这个......也许我把你的想法与我最后的回答结合起来:-)只是因为我需要这种能力,只需要调用验证方法......当我想通过ajax调用服务验证以显示“实时”错误 – Simon

-1

下面刚进入我的脑海......你觉得:

我改变我的服务的方法:

public IValidationResult Publish(JobPosting jobPosting, bool validateOnly = false){ 
    var validationResult = ValidatePublish(jobPosting); 
    if(validateOnly) return validationResult; 

    jobPosting.State = JobPostingState.Published; 
    ... 
    return validationResult; 
}   

然后在控制器我总是只能调用发布方法,而不是额外的ValidatePublish了:

public ActionResult Publish(PublishViewModel model) 
{ 
    var validationResult = _jobService.Publish(jobPosting); 
    if(!validationResult.Success) return View("error", validationResult); 
} 

当我只需要简单的验证我做

var validationResult = _jobService.Publish(jobPosting, true); 

这是做这样的okey吗? 或者,如果正常服务调用返回IValidationResult,是不是很好看?

+0

或者您认为每种服务方法实现某种结果更好吗? – Simon