在用MVC4开发了几年之后,我开始了一个新的ASP.NET项目,我有一个关于架构的问题。
在每个页面的上角,我将显示当前登录用户的详细信息。
在MVC4中,我通过创建一个BaseController实现了类似的功能,它创建了一个EF数据连接,并设置了一些在每个页面上都会使用的通用变量- CurrentUser就是其中之一。
现在我使用的是Core,这种方法似乎不起作用,当然也不是可模仿的。
通过ASP.NET核心实现这样的事情的正确方法是什么?
我需要在每个视图上使用相同的变量,当然也不希望在每个控制器操作中都编写代码!
发布于 2018-04-20 16:56:14
您可以使用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 );
}
}
可以强类型Create view file @ 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")属性来修饰控制器,并定义公共IViewComponentResult Invoke()或公共IViewComponentResult InvokeAsync()来将它们转换为混合控制器-视图组件。
https://stackoverflow.com/questions/49944171
复制相似问题