在我的主页(索引)页面上,如果用户未登录,我希望登录表单直接位于我的主页,但如果用户已经登录,则将显示索引页面。如果我使用style
此页面按预期加载,但是在帐户I等文件夹中的其他页面出现错误
CSHTML:
_LoginPartial
`InvalidOperationException:传递给的模型项 ViewDataDictionary的类型为' CS.Pages.Manifest.IndexModel',但是这个 ViewDataDictionary实例需要类型的模型项 ' CS.Pages.Account.LoginModel'
LoginModel构造函数:
@if (SignInManager.IsSignedIn(User))
{
<p> Welcome to my website</p>
}
else
{
@await Html.PartialAsync("Account/Login")
}
答案 0 :(得分:2)
当您加载部分内容时:
@await Html.PartialAsync("Account/Login")
您调用它的视图模型是隐式传递的,就像您已经完成的那样:
@await Html.PartialAsync("Account/Login", Model)
因此,您收到的错误。部分期望LoginModel
类型的模型,但您将其传递给IndexModel
类型的模型。当然,解决方案是传递正确类型的模型,即LoginModel
。但是,您的LoginModel
必须使用SignInManager<ApplicationUser>
和ILogger<LoginModel
类型的参数构建。因此,当您尝试仅传递new LoginModel()
时,您收到第二个错误的原因。
所有这一切都归结为这首先是部分的不当使用。需要这种实例化复合体的部分应该是view component,这样可以让您在设置时获得更大的灵活性,并且允许您进行注射,这就是您所需要的。在这里需要。
基本上,您只需创建一个继承自ViewComponent
的类并实现方法InvokeAsync
:
public class LoginViewComponent : ViewComponent
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger<LoginModel> _logger;
public LoginViewComponent(SignInManager<ApplicationUser> signInManager, ILogger<LoginModel> logger)
{
_signInManager = signInManager;
_logger = logger;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var model = await GetModelAsync().ConfigureAwait(false);
return View(model);
}
public Task<LoginModel> GetModelAsync()
{
return Task.FromResult(new LoginModel(_signInManager, _logger));
}
}
请注意,视图组件的构造函数采用了实例化LoginModel
所需的参数。这允许框架注入这些依赖项。然后,构造函数只将它们存储在一些私有字段中。
InvokeAsync
方法调用GetModelAsync
以获取LoginModel
实例,然后返回使用此模型的视图。由于此处没有需要完成的实际异步工作,因此GetModelAsync
方法只会返回根据新增Task
的结果创建的LoginModel
。必须这样做才能满足Task
- 返回InvokeAsync
的性质。如果你真的需要异步的东西,你可以简单地等到这里。
有了这个,你只需要创建视图Views\Shared\Components\Login\Default.cshtml
。哪个会包含您当前正在使用的部分视图的内容。 Login\Default.cshtml
部分按惯例。该目录是视图组件类的名称,减去ViewComponent
后缀,Default.cshtml
是它将在那里查找的默认视图。如果您愿意,可以自定义,但实际上没有理由。
最后,只要您想要显示,只需致电:
@await Component.InvokeAsync("Login");
使用is方法,所有功能(包括模型的创建和传递)都是自包含的,因此可以将其称为任何地方,无论是在单个视图中,还是在您的布局中
答案 1 :(得分:1)
尝试将LoginModel实例传递给局部视图
@if (SignInManager.IsSignedIn(User))
{
<p> Welcome to my website</p>
}
else
{
@await Html.PartialAsync("Account/Login", new LoginModel())
}