业务/服务层

时间:2016-08-26 08:30:48

标签: asp.net asp.net-mvc validation service-layer business-logic-layer

我问这个是因为经过长时间的搜索后我还没有找到一个好的答案......

这就是我想要的:

示例:我有一个域模型“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以在视图中显示验证错误。但是,当验证失败时,我必须永远无法发布作业。 因此,为了让我的代码更加健壮,我在服务层的Publish方法中添加了第二个验证检查:

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

但是我对这种方法没有这么好的感觉,因为现在我在每个控制器发布请求期间验证正常时调用了两次验证。

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

提前感谢您对此的看法!!!

2 个答案:

答案 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);
}

答案 1 :(得分:-1)

以下只是我的想法...你怎么想:

我将服务方法更改为:

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

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

然后在控制器中我总是只调用Publish方法而不再调用额外的ValidatePublish:

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

当我只需要简单验证时,

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

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