【发布时间】:2016-10-26 20:13:42
【问题描述】:
我正在构建一个 asp mvc 5 支持票帮助台应用程序。该应用程序将要求用户注册以提交支持票。用户的操作是通过像线程一样添加注释来更新票证。
代理将管理工单,并拥有编辑工单、创建内部和公共注释以及查看所有工单的额外权限。
有一个站点管理员可以配置站点。
问题是,如果我有一个称为工单控制器的控制器,则创建或编辑工单的主要操作对于代理和用户来说都是相似的。不同之处在于,当用户创建工单时,他们只能填写表单上的某些字段,而代理可以更新其他字段。
所以我最终会在我的控制器和视图中使用大量 if then else 语句来检查用户角色,从而限制向不同类型的用户显示哪些表单字段和操作。此外,我的视图模型正在向客户公开他们不应该拥有权限的属性。
所以我的问题是你如何组织这种类型的设置。您是否为代理创建单独的区域并复制所有控制器和视图模型以满足此类用户的需求。
或者您是否会为创建的每种不同类型的用户角色使用 if then else 语句来膨胀控制器和视图?
我们将不胜感激有关此特定应用程序的最佳实践的建议。
为代理创建区域的唯一好处是我可以彻底改变代理门户的外观和感觉,例如使用不同的 URL。 mysite/agentdesk/tickets,它会更容易维护,但会以重复代码为代价。
/* 当前控制器逻辑和视图模型 */ 如您所见,视图模型中公开了只有代理才能设置的状态和优先级属性。
在控制器的create方法中,你可以看到teneray操作符被用来判断用户是否有正确的角色来设置上述属性。
public class TicketViewModel
{
public int Id { get; set; }
[Required]
public string Subject { get; set; }
[Required]
public string Description { get; set; }
// Only an agent can change the status
[Required]
public int Status { get; set; }
// Only an agent can change the priority
[Required]
public int Priority { get; set; }
public IEnumerable<StatusType> StatusTypes { get; set; }
public IEnumerable<PriorityLevel> PriorityLevels { get; set; }
}
public class TicketController : Controller
{
[Authorize]
public ActionResult Create()
{
var viewModel = new TicketViewModel
{
StatusTypes = _context.StatusTypes.ToList(),
PriorityLevels = _context.PriorityLevels.ToList()
};
return View(viewModel);
}
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(TicketViewModel viewModel)
{
if (!ModelState.IsValid)
{
viewModel.StatusTypes = _context.StatusTypes.ToList(),
viewModel.PriorityLevels = _context.PriorityLevels.ToList()
return View(viewModel);
}
bool agentRole = HttpContext.Current.User.IsInRole("Agent");
var ticket = new Ticket
{
CreatedBy = User.Identity.GetUserId(),
Subject = viewModel.Subject,
Description = viewModel.Description,
StatusId = agentRole ? viewModel.Status : 1,
PriorityId = agentRole ? viewModel.Priority : 1
};
_context.Tickets.Add(ticket);
_context.SaveChanges();
return RedirectToAction("Index", "Tickets");
}
}
【问题讨论】:
-
我可能会介绍代理区域,所有控制器都装饰有 [Role("Agent")] 等。关于重复视图,如果您将公共共享字段作为局部视图引入,那么这将减少这一点。关于您的控制器,它们应该尽可能少地保留业务逻辑,因此创建一个名为 TicketCreator 的业务类,例如它包含两个方法 AsAgent 和 AsUser.. 然后您可以从不同的控制器调用每个方法,但共享尽可能多的你喜欢的类中的逻辑
-
补充一下,你的业务类方法也会返回两种不同类型的 ViewModel,这样你就不会向用户发送敏感数据
-
@uk2k05 您能否展示一个名为 TicketCreator 解决方案的业务类示例。我试图弄清楚如何才能将视图模型考虑在内以适应客户和代理。
标签: asp.net-mvc refactoring asp.net-mvc-areas service-layer