簡體   English   中英

如何在另一個頁面中顯示一個頁面?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM