One possible solution would be to create an IContractService interface that has two methods: one to get the contract, and the other to check it:
public IContractService { Contract GetContract(int id); ValidationResult ValidateContract(Contract contract); }
ValidationResult can be an enumeration, just to signal to the calling method how to proceed:
public enum ValidationResult { Valid, Unauthorized, NotFound }
Possible implementation of IContractService :
public class ContractService : IContractService { private readonly ISession _session; private readonly IAuthenticationService _authService; // Use Dependency Injection for this! public ContractService(ISession session, IAuthenticationService authService) { _session = session; _authService = authService; } public Contract GetContract(int id) { var contract = _session.Single<Contract>(contractId); // hanlde somwhere else whether it null or not return contract; } public ValidationResult ValidateContract(Contract contract) { var user = _authService.LoggedUser(); if (contract.CreatedBy == null || !contract.CreatedBy.Id.HasValue || contract.CreatedBy.Id.Value != user.Id) return ValidationResult.Unauthorized; if (contract.Versions.Count < version) return ValidationResult.NotFound; return ValidationResult.Valid; } }
Then in your controller, you can still return various HttpNotFound , etc. in view:
[HttpPost, Authorize(Roles = "User"), ValidateAntiForgeryToken] public virtual ActionResult GetSignatories(string contractId, int version) { //NOTE Should be extracted var contract = _contractService.GetContract(contractId); if (contract == null) return HttpNotFound(); var result = _contractService.ValidateContract(contract); if (result == ValidationResult.Unauthorized) return new HttpUnauthorizedResult(); if (result == ValidationResult.NotFound) return HttpNotFound(); return Json(contract.CurrentVersion.Tokens.Select(x => x.User).ToList()); }
source share