【发布时间】:2020-06-24 19:10:54
【问题描述】:
我有一个模式用于根据用户角色更改通用控制器的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();
}
【问题讨论】:
-
您考虑过使用
[Authorize]属性吗? docs.microsoft.com/en-us/aspnet/web-api/overview/security/… -
^^ 如果他们不在角色中,那只会向他们显示拒绝访问页面。看起来他想根据他们的角色动态更改视图
-
可能您想编写一个自定义 Filter,它将根据他们的角色重定向到正确的操作
-
第一件事是保持代码 S-O-L-I-D。由于每个场景都在做同样的事情,我会用多态性替换条件语句。这将是重构代码的良好开端,并且会真正清除您可以使用的任何设计模式,因此您不必复制和粘贴。如上所述,过滤器属性可以很好地工作,但我会先清理条件语句。
-
我将从接口和对象开始。
IHomeView使用 '.GetView() 和 GetViewBag' 之类的方法以及homeVendorView: IHomeView之类的类我还将重构httpContext和Helper注入带有一些 IOC 容器的类构造函数中,这样你就不会每节课都要传给他们。如果我有更多时间,我可以试着做点什么。
标签: c# asp.net-mvc asp.net-core roles