我有一个控制器,它具有方法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