[英]How to feature a page in another page?
在我的主頁(索引)頁面上,如果用戶尚未登錄,但我想讓登錄表單直接位於我的主頁上,但是如果用戶已經登錄,則將顯示索引頁面。 如果我使用_LoginPartial
則會按預期加載此頁面,但是與文件夾(如Account)中的其他頁面一樣,我會收到錯誤消息
CSHTML:
@if (SignInManager.IsSignedIn(User))
{
<p> Welcome to my website</p>
}
else
{
@await Html.PartialAsync("Account/Login")
}
`InvalidOperationException:傳遞到ViewDataDictionary的模型項的類型為'CS.Pages.Manifest.IndexModel',但是此ViewDataDictionary實例需要類型為'CS.Pages.Account.LoginModel'的模型項。
LoginModel構造函數:
public LoginModel(SignInManager<ApplicationUser> signInManager, ILogger<LoginModel> logger)
{
_signInManager = signInManager;
_logger = logger;
}
當您加載部分像:
@await Html.PartialAsync("Account/Login")
您從中調用視圖的模型將隱式傳入,就像您完成了一樣:
@await Html.PartialAsync("Account/Login", Model)
因此,您收到的錯誤。 該Partial期望使用LoginModel
類型的模型,但是您要向其傳遞IndexModel
類型的模型。 解決方案當然是傳遞正確類型的模型,即LoginModel
。 然而,你的LoginModel
已經將與構造有類型的參數SignInManager<ApplicationUser>
和ILogger<LoginModel
。 因此,為什么在嘗試僅傳遞new LoginModel()
時收到第二個錯誤。
實際上,所有這些歸結為首先是對局部的不正確使用。 實際上,需要這種復雜實例化的部分實際上應該是視圖組件 ,這將為您提供更多的設置靈活性, 並允許您進行注入,這是您在這里需要的。
本質上,您只需創建一個繼承自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
方法只返回根據更新LoginModel
的結果創建的Task
。 這有工作要做,以滿足Task
的-returning性質InvokeAsync
。 如果您實際上需要異步操作,則可以在這里等待。
有了這個,您只需要創建Views\\Shared\\Components\\Login\\Default.cshtml
視圖。 其中將包含您當前正在使用的部分視圖的內容。 按照慣例, Login\\Default.cshtml
部分。 該目錄是視圖組件類的名稱,減去ViewComponent
后綴, Default.cshtml
是它將在此處查找的默認視圖。 您可以根據需要對此進行自定義,但實際上沒有理由。
最后,在您希望顯示的地方,只需調用:
@await Component.InvokeAsync("Login");
使用is方法,所有功能(包括模型的創建和傳入)都是獨立的,因此可以在任何地方 (在單個視圖中,甚至在布局中)調用它。
嘗試將LoginModel實例傳遞到局部視圖
@if (SignInManager.IsSignedIn(User))
{
<p> Welcome to my website</p>
}
else
{
@await Html.PartialAsync("Account/Login", new LoginModel())
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.