質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

1回答

1649閲覧

Controllerにログインページに直接飛ぶアクションを追加すると正常な挙動をしない。

Mk-ky

総合スコア19

.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2021/07/08 01:06

編集2021/07/08 08:32

前提・実現したいこと

https://teratail.com/questions/347736
この質問を前提としています。
この質問の回答により、「ログインページを初期画面にするにはControllerそのものに[Authorize]属性をつければ匿名ユーザーがそのそのアクションをしてきた際にログインページにリダイレクトすることができるとわかりました。

ですがControllerに直接ログインページに飛ぶアクションを追加しそれをStartUpから動くように設定すると正常に動いてくれない理由がわかりません。 
後学のために[Authorize]属性を使わず匿名ユーザーがアクセスしてきた場合ログインページに飛ばす方法を知りたいです。

##試したこと
HomeControllerにログインページのcshtmlに飛ぶアクションを追加しました。
次にStartup.csをこれが最初に実行されるアクションになるよう変更しました。

#####HomeContolloer

C#

1using Microsoft.AspNetCore.Mvc; 2using Microsoft.Extensions.Logging; 3using System; 4using System.Collections.Generic; 5using System.Diagnostics; 6using System.Linq; 7using System.Threading.Tasks;  8using プロジェクト.Models; 9using Microsoft.AspNetCore.Authorization; 10 11namespace プロジェクト.Controllers 12{ 13 14 [Authorize] 15 public class HomeController : Controller 16 { 17 private readonly ILogger<HomeController> _logger; 18 19 20 public HomeController(ILogger<HomeController> logger) 21 { 22 _logger = logger; 23 } 24 25 26 27 public IActionResult Index() 28 { 29 return View(); 30 } 31 32 public IActionResult Privacy() 33 { 34 return View(); 35 } 36 37 38    //ここから追加 39 public IActionResult Login() 40 { 41 return View("Areas/Identity/Pages/Account/Login.cshtml"); 42 } 43    //ここまで追加 44 45 46 [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 47 public IActionResult Error() 48 { 49 return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 50 } 51 } 52} 53

#####Startup.cs

C#

1using Microsoft.AspNetCore.Builder; 2using Microsoft.AspNetCore.Hosting; 3using Microsoft.AspNetCore.HttpsPolicy; 4using Microsoft.AspNetCore.Identity; 5using Microsoft.AspNetCore.Identity.UI; 6using Microsoft.EntityFrameworkCore; 7using Microsoft.Extensions.Configuration; 8using Microsoft.Extensions.DependencyInjection; 9using Microsoft.Extensions.Hosting; 10using System; 11using System.Collections.Generic; 12using System.Linq; 13using System.Threading.Tasks; 14using プロジェクト.Data; 15 16namespace プロジェクト 17{ 18 public class Startup 19 { 20 public Startup(IConfiguration configuration) 21 { 22 Configuration = configuration; 23 } 24 25 public IConfiguration Configuration { get; } 26 27 // This method gets called by the runtime. Use this method to add services to the container. 28 public void ConfigureServices(IServiceCollection services) 29 { 30 services.AddRazorPages(); 31 32 services.AddDbContext<ApplicationDbContext>(options => 33 options.UseSqlServer( 34 Configuration.GetConnectionString("DefaultConnection"))); 35 services.AddDatabaseDeveloperPageExceptionFilter(); 36 37 services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) 38 .AddEntityFrameworkStores<ApplicationDbContext>(); 39 services.AddControllersWithViews(); 40 } 41 42 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 43 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 44 { 45 if (env.IsDevelopment()) 46 { 47 app.UseDeveloperExceptionPage(); 48 app.UseMigrationsEndPoint(); 49 } 50 else 51 { 52 app.UseExceptionHandler("/Home/Error"); 53 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 54 app.UseHsts(); 55 } 56 app.UseHttpsRedirection(); 57 app.UseStaticFiles(); 58 59 app.UseRouting(); 60 61 app.UseAuthentication(); 62 app.UseAuthorization(); 63 64 app.UseEndpoints(endpoints => 65 { 66 endpoints.MapRazorPages(); 67 endpoints.MapControllerRoute( 68 name: "default", 69 pattern: "{controller=Home}/{action=Login}/{id?}"); 70 }); 71 } 72 } 73} 74

以下ログインページのコード
#####Login.cshtml

Razor

1@page 2 3@model LoginModel 4 5@{ 6 ViewData["Message3"] = "ログイン"; 7} 8 9<h1> @ViewData["Message3"] </h1>  10<div class="row"> 11 <div class="col-md-4"> 12 <section> 13 <form id="account" method="post"> 14 <h4>IDを入力してログインします</h4> 15 <hr /> 16 <div class="form-group"> 17 <label asp-for="Input.Email">ID</label> 18 <input asp-for="Input.Email" class="form-control" /> 19 <span 9="Input.Email" class="text-danger"></span> 20 </div> 21 <div class="form-group"> 22 <label asp-for="Input.Password">パスワード</label> 23 <input asp-for="Input.Password" class="form-control" /> 24 <span asp-validation-for="Input.Password" class="text-danger"></span> 25 </div> 26 <div class="form-group"> 27 <div class="checkbox"> 28 <label asp-for="Input.RememberMe"> 29 30 <input asp-for="Input.RememberMe" /> 31 @Html.DisplayNameFor(m => m.Input.RememberMe) 32 33 </label> 34 </div> 35 </div> 36 <div class="form-group"> 37 <button type="submit" class="btn btn-primary">Log in</button> 38 </div> 39 40 </form> 41 </section> 42 </div> 43</div> 44 45@section Scripts { 46 <partial name="_ValidationScriptsPartial" /> 47} 48

起きてるエラー

まずこの状態で起動するとLogin.cshtmlの 6行目 ViewData["Message3"] = "ログイン"; の部分に NullReferenceException: Object reference not set to an instance of an object が表示され実行できません。
NullReferenceException

次に@pageディレクティブを外し9行目にタイトルを直打ちした状態で起動するとログインページ自体に飛ぶことはできましたがログインボタンを押した後画面が遷移しません。
ブレイクポイントを置いて確認したところLogin.cshtml.csが動いていないことがわかりました。

開発環境

Windows 10 Pro 19043.1083
Microsoft Visual Studio Community 2019 Version 16.9.4
ログインに関するコードはASP.netIdentityの「個別のアカウント」を使い生成しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ブレイクポイントを置いて確認したところLogin.cshtml.csが動いていないことがわかりました。

それが NullReferenceException の原因でしょう。

View(string) というオーバーロードは "Creates a ViewResult object by specifying a viewName." ということで、ページモデル (cshtml.cs) は動かないのですが、その場合 ViewData.get は null を返すよいうことのようです。

Controller Class
https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controller?view=aspnetcore-5.0

Redirect(string) と使って Login ページにリダイレクトすれば動くと思います。string は Login ページの url にしてください。Razor ページなので Areas/Identity/Pages/Account/Login ではないことに注意。以下のような感じ。

public IActionResult Index() { if (!User.Identity.IsAuthenticated) { return Redirect("/Identity/Account/Login"); } return View(); }

上記で、ユーザーが Home/Index にアクセスしてくると、そのユーザーが認証されない場合 (User.Identity.IsAuthenticated が false) は Login ページにリダイレクトされるはずです。

投稿2021/07/08 04:10

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Mk-ky

2021/07/08 05:37 編集

ありがとうございます! 完全に思い通りの動きにできました! 二つ疑問があり一つはcshtmlの中ででViewDataに値を格納しているのにnullになるのはなぜですか? 二つ目はView@modelディレクティブでLoginmodelを指定しているのにcshtml.csが動かないのはなぜですか? viewだけが返されてもviewの中のコードにそれらが書かれているはずなので動くのではないのかと思いました。
退会済みユーザー

退会済みユーザー

2021/07/08 07:53 編集

普通ではやらないことをして普通でないエラーが出ているよいうな気がしますが・・・ > cshtmlの中ででViewDataに値を格納しているのにnullになるのはなぜですか? Razor の .cshtml (ページファイル) と .cshtml.cs (ページモデル) は一体モノで、MVC の .cshtml (ビュー) とは違うものだから、MVC のビューのように retrun View("xxx.cshtml") とはできないということだと思います。 @page (Razor ディレクティブ) を外して動きが変わるということがそれを裏付けているのでは? 外すことによって ASP.NET がそのページを Razor ページとして処理しなくなる(なので、ViewData["xxx"] で NullReferenceException が出なくなる)のではないかと思います。 以上は想像です。その想像を裏付ける公式ドキュメントは見つけられていません。(普通そんなことはしないので、そんなことが書いてあるドキュメントは見つからないのではないかと勝手に思ってます) > View@modelディレクティブでLoginmodelを指定しているのにcshtml.csが動かないのはなぜですか? LoginModel は渡せてません。ViewData 周りのコードをコメントアウトして NullReferenceException を回避して試してみてください。asp-for="Input.Email" あたりでエラーになると思います。 そのあたりは MVC のビューでも同じで、アクションメソッド無しでは Model を使うあたりでエラーになるはずです。 とにかく普通はやらないことをやって、それで出てくるエラーが何故かを詮索してもあまり実のある話にはならないかと思います。 このあたりで本スレッドの話は終わりにしませんか。
Mk-ky

2021/07/08 08:05

ありがとうございます。 なにか勉強になるかと思ったのですが、こちらも変なことを試してみて起きる変なエラーについて質問して時間を取らせてしまい申し訳ありませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問