2017-11-09 5 views
0

私のホーム(インデックス)ページで、ユーザーがログインしていない場合はログインフォームを直接私のホームページに置いておきたいが、ユーザーが既にログインしている場合はインデックスページが表示される。私は_LoginPartialを使用している場合、このページは予想通りロードされ、しかし、そのようなアカウントとしてフォルダ内の他のページと私はエラー別のページにページを表示するにはどうすればいいですか?

CSHTML取得されています ViewDataDictionaryに渡されたモデルアイテム:

@if (SignInManager.IsSignedIn(User)) 
{ 
    <p> Welcome to my website</p> 
} 
else 
{ 
    @await Html.PartialAsync("Account/Login") 
} 

`InvalidOperationExceptionがします'CS.Pages.Manifest.IndexModel'タイプですが、この ViewDataDictionaryインスタンスには、 'CS.Pages.Account.LoginModel'のモデルアイテムが必要です。

LoginModelコンストラクタ:

public LoginModel(SignInManager<ApplicationUser> signInManager, ILogger<LoginModel> logger) 
{ 
    _signInManager = signInManager; 
    _logger = logger; 
} 

答えて

2

にLoginModelインスタンスを渡してみてください。

@await Html.PartialAsync("Account/Login") 

ビューのモデルあなたはそれを暗黙のうちに渡して呼び出すことになります。まるであなたがしたかのように:

@await Html.PartialAsync("Account/Login", Model) 

したがって、受け取ったエラー。 partialはLoginModel型のモデルを想定していますが、IndexModel型のモデルを渡しています。その解決策は、正しいタイプのモデル、すなわちLoginModelを渡すことです。ただし、LoginModelは、SignInManager<ApplicationUser>ILogger<LoginModelのパラメータで構成する必要があります。したがって、あなたはちょうどnew LoginModel()を渡そうとしたときに2番目のエラーを受け取ったのです。

これはすべて、最初は部分的に不適切な使い方であるということです。このインスタンス化の複合体を必要とする部分は実際にはview componentでなければなりません。では、ここで必要とされる注入を行うことができます。ビューコンポーネントのコンストラクタは、あなたがLoginModelでインスタンス化する必要があるパラメータを取ること

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)); 
    } 
} 

お知らせ:

基本的に、あなただけのViewComponentから継承し、メソッドInvokeAsyncを実装するクラスを作成します。これにより、フレームワークによってこれらの依存関係が挿入されます。その場合、コンストラクタは単にこれらをいくつかのプライベートフィールドに格納します。

InvokeAsyncメソッドは、LoginModelインスタンスを取得するためにGetModelAsyncを呼び出し、このモデルを使用するビューを返します。ここでは、実行する必要がある実際の非同期作業がないので、GetModelAsyncメソッドは、LoginModelの新規作成結果から作成されたTaskを返します。これはTask - 返品の性質InvokeAsyncを満たすために行わなければなりません。実際に非同期にする必要がある場合は、代わりにここで単に待つことができます。

これを実行すると、ビューViews\Shared\Components\Login\Default.cshtmlを作成するだけで済みます。現在使用している部分ビューの内容を持つでしょう。 Login\Default.cshtml部分は慣例によるものです。ディレクトリは、ビューコンポーネントクラスの名前で、接尾辞ViewComponentを引いたもので、Default.cshtmlがデフォルトのビューです。あなたが好きなら、これはカスタマイズすることができますが、本当に理由はありません。最後に

、あなたはこれを表示したい場所、あなたは、単に呼び出す:

@await Component.InvokeAsync("Login"); 

ではアプローチであり、(作成などとモデルの中に渡して)すべての機能はすべて自己完結しているので、これはすることができます個々のビュー、またはあなたのレイアウトのいずれかで、どこでもと呼ぶことができます。

0

あなたは部分などをロードすると部分図

@if (SignInManager.IsSignedIn(User)) 
{ 
    <p> Welcome to my website</p> 
} 
else 
{ 
    @await Html.PartialAsync("Account/Login", new LoginModel()) 
} 
+0

私は '@model IndexModel'を持っているので、インデックスモデルが必要です。' 1つ以上のコンパイル参照がありません。あなたのプロジェクトが 'Microsoft.NET.Sdk.Web'を参照し、 'PreserveCompilationContext'プロパティがfalseに設定されていないことを確認してください。 – Decoder94

+0

LoginModel()インスタンスの代わりにnullを渡すとどうなりますか? - '@await Html.PartialAsync(" Account/Login "、null)'。 IndexModelがLoginModelを必要とするLoginビューに渡されているので、あなたは 'InvalidOperationException 'を取得していたと思います。そして、あなたがコメントで述べた2番目のエラーを理解できませんでした。あなたはこれを取得しているときに詳細を教えていただけますか? – Manu

+0

'@await Html.PartialAsync(" Account/Login "、新しいLoginModel())' I got this 'を使用したときに必要な仮引数 'loginModel.LoginModel(SignInManager < ViewDataDictionaryに渡されたモデルアイテムは 'CS.Pages.IndexModel'タイプですが、このViewDataDictionaryインスタンスには 'CS.Pages.Account'タイプのモデルアイテムが必要です.LoginModel'.'私の質問にログインコンストラクタを追加しました。 – Decoder94

関連する問題