我在MVC4开发几年后开始一个新的ASP.NET项目,我对架构有疑问。
在每个页面的上角,我将显示当前登录用户的详细信息。
在MVC4中,我通过创建一个创建EF数据连接的BaseController来实现这样的功能,并设置了一些将在每个页面上使用的公共变量 - CurrentUser就是其中之一。
现在我正在使用Core,这种方法似乎不起作用,当然也不可模仿。
通过ASP.NET Core实现这样的目标的正确方法是什么?
我在每个视图上都需要相同的变量,当然也不想在每个控制器动作中编写代码!
答案 0 :(得分:0)
您可以在asp.net核心中使用View Components功能来实现该功能。
//In your ConfigureServices method , add your services that will be injected whenever view component is instantiated
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton<IUserRespository, UserRepository>();
}
//Now Create a view component
public class LoggedInUser : ViewComponent
{
private IUserRespository userRepository;
//Services can be injected using asp.net core DI container
public LoggedInUser(IUserRepository userRepository,SomeOtherService service)
{
//assign services to local variable for use later
this.userRepository = userRepository;
}
//This method can take any number of parameters and returns view
public async Task<IViewComponentResult> InvokeAsync(int param1,string param2,etc )
{
//get the logged in user data here using available services
var loggedInUserData = GetSomeData(context);
return View(loggedInUserData );
}
}
创建视图文件@View / Shared / Components / LoggedInUser / Default.cshtml.View可以强类型化。
@model LoggedInUserModel
<div>
<!-- html here to render model -->
</div>
现在,由于您使用在每个页面上显示此数据,因此需要将_Layout.chstml应用于所有页面。在_Layout.chstml中,您可以使用要作为匿名类型传递的任何其他参数呈现上面定义的视图组件。
@await Component.InvokeAsync("LoggedInUser", new { param1=value,param2=value,etc })
测试视图组件:
var mockRepository = Mock of ICityRepository;
var viewComponent= new LoggedInUser(mockRepository);
ViewViewComponentResult result
= viewComponent.Invoke() as ViewViewComponentResult; //using Invoke here instead of InvokeAsnyc for simplicity
//Add your assertions now on result
注意: 也可以使用 [ViewComponent(Name =“ComponentName”)] 属性修饰控制器并定义public IViewComponentResult Invoke() 或公共IViewComponentResult InvokeAsync()将它们转换为混合控制器 - 视图组件。