我有一個控制器,它具有方法GetSignatories(),AddMe(),RemoveMe(),AddUser(),RemoveUser()等等,以便我必須每次驗證如果合同存在,用戶是否有權訪問合同以及是否存在請求的版本。我想知道我應該在哪裏放這個代碼?在一個服務中或者用我的控制器的其他方法提取?我的問題是,我soometime返回Unathorized或NotFound,不知道什麼是最好的方式來做到這一點。在控制器中重複授權代碼的最佳做法
這裏是我的控制器:
public partial class ContractController : Controller
{
private ISession _session;
private IAuthenticationService _authService;
public V1Controller(ISession session, IAuthenticationService authService)
{
_session = session;
_authService = authService;
}
[HttpPost]
[Authorize(Roles = "User")]
[ValidateAntiForgeryToken]
public virtual ActionResult GetSignatories(string contractId, int version)
{
//NOTE Should be extracted
var contract = _session.Single<Contract>(contractId);
if (contract == null) return HttpNotFound();
var user = _authService.LoggedUser();
if (contract.CreatedBy == null || !contract.CreatedBy.Id.HasValue || contract.CreatedBy.Id.Value != user.Id) return new HttpUnauthorizedResult();
if (contract.Versions.Count < version) return HttpNotFound();
/*NOTE END Should be extracted */
return Json(contract.CurrentVersion.Tokens.Select(x => x.User).ToList());
}
[HttpPost]
[Authorize(Roles = "User")]
[ValidateAntiForgeryToken]
public virtual ActionResult AddMe(string contractId, int version)
{
//NOTE Should be extracted
var contract = _session.Single<Contract>(contractId);
if (contract == null) return HttpNotFound();
var user = _authService.LoggedUser();
if (contract.CreatedBy == null || !contract.CreatedBy.Id.HasValue || contract.CreatedBy.Id.Value != user.Id) return new HttpUnauthorizedResult();
if (contract.Versions.Count < version) return HttpNotFound();
/*NOTE END Should be extracted */
return AddUserToContract(contract, new UserSummary(user));
}
[HttpPost]
[Authorize(Roles = "User")]
[ValidateAntiForgeryToken]
public virtual ActionResult RemoveMe(string contractId, int version)
{
//NOTE Should be extracted
var contract = _session.Single<Contract>(contractId);
if (contract == null) return HttpNotFound();
var user = _authService.LoggedUser();
if (contract.CreatedBy == null || !contract.CreatedBy.Id.HasValue || contract.CreatedBy.Id.Value != user.Id) return new HttpUnauthorizedResult();
if (contract.Versions.Count < version) return HttpNotFound();
/*NOTE END Should be extracted */
return RemoveUserFromContract(contract, new UserSummary(user));
}
[HttpPost]
[Authorize(Roles = "User")]
[ValidateAntiForgeryToken]
public virtual ActionResult AddUser(string contractId, int version, UserSummary userSummary)
{
//NOTE Should be extracted
var contract = _session.Single<Contract>(contractId);
if (contract == null) return HttpNotFound();
var user = _authService.LoggedUser();
if (contract.CreatedBy == null || !contract.CreatedBy.Id.HasValue || contract.CreatedBy.Id.Value != user.Id) return new HttpUnauthorizedResult();
if (contract.Versions.Count < version) return HttpNotFound();
/*NOTE END Should be extracted */
return AddUserToContract(contract, userSummary);
}
[HttpPost]
[Authorize(Roles = "User")]
[ValidateAntiForgeryToken]
public virtual ActionResult RemoveUser(string contractId, int version, UserSummary userSummary)
{
//NOTE Should be extracted
var contract = _session.Single<Contract>(contractId);
if (contract == null) return HttpNotFound();
var user = _authService.LoggedUser();
if (contract.CreatedBy == null || !contract.CreatedBy.Id.HasValue || contract.CreatedBy.Id.Value != user.Id) return new HttpUnauthorizedResult();
if (contract.Versions.Count < version) return HttpNotFound();
/*NOTE END Should be extracted */
return RemoveUserFromContract(contract, userSummary);
}
}
對於那些誰可能會尋求如何在全球註冊模型綁定:
public static void RegisterModelBinders()
{
var session = (ISession)DependencyResolver.Current.GetService(typeof(ISession));
var authService = (IAuthenticationService)DependencyResolver.Current.GetService(typeof(IAuthenticationService));
System.Web.Mvc.ModelBinders.Binders[typeof (Contract)] = new ContractModelBinder(session, authService);
}
對於那些希望在這裏ModelBinder的如何進行單元測試是一個良好的開端:http://stackoverflow.com/questions/1992629/unit-testing-custom-model-binder-in-asp-net-mvc-2 – VinnyG 2011-04-09 18:57:06