public ActionResult Index(int ehrId, int? page)
{
EHR ehr = ehrRepository.FindById(ehrId);
if (ehr.UserName != User.Identity.Name)
return View("Invalid Owner");
var physicaltests = ehr.PhysicalTests.Where(test=>!test.IsDeleted).OrderByDescending(test => test.CreationDate);
List<PhysicalTestListItem> physicalTestsVM = new List<PhysicalTestListItem>();
Mapper.Map(physicaltests, physicalTestsVM);
var paginatedTests = physicalTestsVM.ToPagedList(page ?? 0, PAGESIZE);// new PaginatedList<PhysicalTestListItem>(physicalTestsVM, page ?? 0, pageSize);
return View(paginatedTests);
}
public ActionResult Create(int ehrId)
{
EHR ehr = ehrRepository.FindById(ehrId);
if (ehr.UserName != User.Identity.Name)
return View("Invalid Owner");
return View(new PhysicalTestForm());
}
我的PhysicalTestsController
中的所有方法都在执行前执行这三行代码。我怎样才能重构这个以避免这么多的重复?我只包含了两种方法,但实际上有六种方法。
答案 0 :(得分:1)
我会这么认为
动作过滤器适用于验证输入数据。
例如
EHR ehr = ehrRepository.FindById(ehrId);
if (ehr.UserName != User.Identity.Name)
return View("Invalid Owner");
适合放入动作过滤器,我在过去的[需要登录]或[RequiresSSL]中创建了其他输入验证,以便多个动作可以共享相同的代码(onBeforeExcuting或onAfterExecuted)。
面向方面的跨领域问题编程
然而,其他一些事项,例如Logging,这是跨架构的所有层面的交叉问题,您可能需要研究AOP(面向方面编程)以帮助避免重复代码。
更新 - 示例代码(未经测试)
public class CheckValidUserAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
IMyRepository myRepository = IoC.Resolve<IMyRepository>();
Int64 userId;
if(Int64.TryParse(filterContext.HttpContext.Request.QueryString["id"]), out userId))
if(!IsValidUser(userId))
filterContext.Result = new InvalidUserResult();
}
public bool IsValidUser(IMyRepository myRepository, Int64 userId)
{
EHR ehr = ehrRepository.FindById(ehrId);
return ehr != null && ehr.UserName == User.Identity.Name;
}
}
像上面这样的东西应该这样做,你需要创建一个命名视图来返回你的“无效用户”,但这应该是微不足道的。网上应该有很多关于如何创建和使用动作过滤器的例子。我个人从Pro ASP.NET MVC Framework和
中学习