目前我正在寻找处理asp.net mvc中控制器操作内部条件的最佳实践。例如 -
public ActionResult Edit(int Id = 0)
{
var Item = _todoListItemsRepository.Find(Id);
**if (Item == null)
return View("NotFound");
if (!Item.IsAuthorized())
return View("NotValidOwner");**
return View("Edit", Item);
}
以粗体标记的上述两个条件用于控制器内的其他操作。所以,为了不在所有行动中重复这些条件。我使用了以下方法。
[HttpGet]
[Authorize]
[ModelStatusActionFilter]
public ActionResult Edit(int Id = 0)
{
var Item = _todoListItemsRepository.Find(Id);
return View("Edit", Item);
}
public class ModelStatusActionFilterAttribute : ActionFilterAttribute
{
private readonly ITodoListItemsRepository _todoListItemsRepository;
public ModelStatusActionFilterAttribute()
: this(new TodoListItemsRepository())
{
}
public ModelStatusActionFilterAttribute(ITodoListItemsRepository todoListItemsRepository)
{
_todoListItemsRepository = todoListItemsRepository;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
var Id = Convert.ToInt32(filterContext.RouteData.Values["Id"]);
var Item = _todoListItemsRepository.Find(Id);
if (Item == null)
{
filterContext.Result = new ViewResult() { ViewName = "NotFound" };
}
else if (!Item.IsAuthorized())
{
filterContext.Result = new ViewResult() { ViewName = "NotValidOwner" };
}
}
catch
{
}
}
}
我不确定这是否是处理此类方案的最佳做法。那么,有人可以提出建议吗?
此致 拉姆
答案 0 :(得分:0)
通常,您不会对Web应用程序的所谓业务逻辑使用动作过滤器 - 这就是控制器的用途。动作过滤器更适用于实际逻辑外部的所有内容 - 常见的情况是日志记录,性能测量,检查用户是否经过身份验证/授权(我不认为这是你的情况,尽管你在上面调用了IsAuthorized方法)项“)。
减少代码通常是件好事,但在这种情况下,我不认为将逻辑放在行动是一个好方法,因为你实际上使它有点不可读,并且我的意思中的不可读代码比重复的代码。 此外,特别是在您的情况下,对于所有有效的项目,您实际上两次调用_todoListItemsRepository.Find()(对于每个有效项目),如果这是一些Web服务调用或数据库查找,这可能是昂贵的。
如果代码只是在整个操作过程中重复,请使用以下方法创建一个方法:
private View ValidateItem(Item) {
if (Item == null)
return View("NotFound");
if (!Item.IsAuthorized())
return View("NotValidOwner");
return null; }