c# - 处理控制器绑定角色解析的最佳方法
问题描述
我有一个模式用于ViewResult
根据用户角色更改通用控制器的类型。我经常重用这段代码,因为有时我需要添加ViewBag
项目来处理特殊情况。
困扰我的是我必须复制和粘贴代码,但我想不出一种有效的方法来在不需要大量杂技的控制器之外创建类或方法(在签名中传递控制器和视图包,等)正常运行。
有正确的方法吗?
public async Task<IActionResult> Index()
{
if (User.Identity.IsAuthenticated)
{
string email = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
Profile profile =
await Helper.GetProfile(HttpContext, User.FindFirstValue(ClaimTypes.NameIdentifier));
if (profile == null)
{
return RedirectToAction("Index", "Profile", new { exists = false });
}
else
{
switch (profile.Role)
{
case Role.VendorRepresentative:
ViewBag.Invoices = await Invoices.Instance.GetInvoicesByVendorRepIdAsync(profile.id);
return View("~/Views/Home/VendorRep.cshtml", profile);
case Role.VendorCustomerService:
return View("~/Views/Home/VendorService.cshtml", profile);
case Role.VendorSalesManager:
ViewBag.Invoices = new List<Invoice>();
return View("~/Views/Home/VendorManager.cshtml", profile);
case Role.Distributor:
ViewBag.Invoices = new List<Invoice>();
return View("~/Views/Home/Distributor.cshtml", profile);
default:
return View();
}
}
}
return View();
}
解决方案
当您集中一个流程时会发生这种情况。它必须包含标识每个消费者组的逻辑,并且必须包含每个消费者的处理过程。
您重用相同的模型,然后将那些特定于消费者的“附加”附加到 ViewBag 的事实仅证明该模型不能代表流程。当一个流程对每个消费者群体只有很小的变化时,模型就像一个产品系列。每个组都由一个变体表示。这些场景将鼓励您设计一个基本模型。例如,您可以将角色枚举与它们各自的索引视图以及可能修改的操作相关联。为了真正代表一个产品系列,您的模型应该为您倾倒在那里的 ViewBag 项目分配空间。
但是,为变体标准化(集中化)核心产品并不能防止需求发生冲突。经理将希望模拟用户或为用户页面访问加上时间戳。一组将希望 UI 元素获取其他人无法访问的数据。产品系列模型一直工作到某个点,直到每个组的请求包含足够的处理以因集中复杂性而需要分离。
http://www.powersemantics.com/p.html
不是通过解释进行处理,这需要阅读整个代码体以确定每个组发生了什么处理,而是通过将请求转换为进程来解决问题。
将流程中的每一步都视为由消费者的索引请求表示。它们不仅由对 Index 的网页调用明确指定,而且可以更改。每个角色的索引请求实际上是它所代表的步骤的复合指令。因此,根据请求变量(Role)发出流程,最后调用序列。
VendorRepresentative
* Authenticate
* Load invoices
Index for VendorRepresentative role translates to -> Auth + LoadInvoices
VendorSalesManager
* Authenticate
* Instantiate invoices
Index for VendorSalesManager role translates to -> Auth + InstantiateInvoices
现在,如果需要添加另一个组,您的流程可以轻松增长。此外,如果您的用户需要控制来运行某个步骤(或不需要,或为其指定值),此模型允许您将他们的参数直接映射到流程指令。