ASP.NET MVC从控制器方法属性传递认证信息给ViewModel
本文关键字:认证 信息 ViewModel 属性 MVC NET 控制器 方法 ASP | 更新日期: 2023-09-27 17:49:48
我正在重新设计一个asp.net MVC后台,以获得完整的多租户支持。
由于我决定使用分片来实现租户之间的完美分离,我需要在每个viewModel中访问一些Auth信息(租户Id),只有使用这些信息,我才能为指定的租户创建正确的连接。
对于传递信息,我有3条规则:
- 我不想使用会话变量 我不想使用ViewBag
- 我不想为每个VM添加一个新的对象来获取认证信息
最重要的是我想要一个"代码更少"的解决方案,完美的场景是在VM内访问认证信息,例如将其作为控制器调用中的属性传递。
我已经重写了controlleronauthorization所以每次调用时它都会将tenantId添加到我的基本控制器(这是我所有控制器的基础)这样我就可以在每个控制器中捕获tenantId,现在我只需要一种方法将tenantId的属性传递给每个VM,就像下面的伪代码
[Authorize]
[TenantId AS A PARAM]
public ActionResult Index()
{
myViewModel vm = new myViewModel();
vm.method();
return this.View(vm);
}
1)将TenantId
放入HttpContext.Curent.Items
TenantId
:
private static int GetTenantId()
{
return HttpContext.Current.Items["TenantId"];
}
3)创建BaseViewModel
public abstract class BaseViewModel
{
public Func<int> GetTenantIdFunc{get;set;}
}
使用依赖注入容器注册你的GetTenantId
函数,并通过属性注入把它注入到你所有的模型中
一种选择是使用基视图模型和继承:
public abstract BaseViewModel()
{
public int TenantId { get; set; }
public void SetAuthInfo(BaseController controller)
{
this.TenantId = controller.TenantId;
}
}
public MyViewModel() : BaseViewModel
// no other changes needed to MyViewModel
...
public ActionResult Index()
{
var model = new MyViewModel();
model.SetAuthInfo(this);
return View(model);
}
通过属性(而不是model.SetAuthInfo
)添加一个动作过滤器并覆盖OnResultExecuted
并将其添加到那里,类似(未经测试):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class SetTenantActionAttribute : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var baseController = filterContext.Controller as BaseController;
if (baseController == null) return;
var model = filterContext.Controller.ViewData.Model as BaseViewModel;
if (model == null) return;
model.TenantId = baseController.TenantId;
}
}
那么你可以把它添加到你的基本控制器(甚至比添加到每个动作更少的代码)