Razor Pages の RedirectToPage メソッドのリダイレクトで InvalidOperationException : No page named ... matches the supplied values. 例外が発生する現象について紹介します。
#TOC(caption="目次")
ASP.NET Core Webアプリケーションを作成し、以下の2つのRazor Pages 作成します。
@page
@model RedirectPage.Pages.wrong_demo.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head>
</head>
<body>
<p>リダイレクトのテストページ</p>
<form method="post">
<input type="submit" value="POST"/>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RedirectPage.Pages.wrong_demo
{
public class IndexModel : PageModel
{
public void OnGet()
{
}
public IActionResult OnPost()
{
return RedirectToPage("/results/destination");
}
}
}
@page "/results/destination"
@{
}
<html>
<head></head>
<body>
<p>リダイレクト先のページです。</p>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace RedirectPage
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
}
/Pages/demo-pagename/main.cshtml ではフォーム内にサブミットボタンを配置しています。クリックによりフォームのポストが実行され、
/Pages/demo-pagename/main.cshtml.cs 内の OnPost メソッドが呼び出され、RedirectToPage() メソッドの呼び出しでページのリダイレクトが実行されます。
/Pages/demo-pagename/dest.cshtml がリダイレクト先です。
@page "/results/destination"
が指定されているため、このページのURLは (アプリケーションルート)/resutls/destination
のURLになります。
アプリケーションの動作を確認します。
(アプリケーションルート)/demo-pagename/main
を開きます。ページが表示され、サブミットボタンが表示されています。
(アプリケーションルート)/demo-pagename/dest
を開きます。こちらのページは page ディレクティブで別の名称が設定されているため表示できません。ページが見つからない旨のエラーメッセージが表示されます。
(アプリケーションルート)/results/destination
を開きます。ページが表示されることが確認できました。
(アプリケーションルート)/demo-pagename/main
に戻りフォーム内のサブミットボタン([]ボタン)をクリックします。
クリックすると、下図の例外画面が表示されます。
以下のメッセージが表示されます。
RedirectToPage
メソッドの第一引数 pageName にはページのリダイレクトURLではなくページのファイル名を指定する必要があります。/Pages/demo-pagename/dest.cshtml
に配置されているファイルのため、"/demo-pagename/dest" を与える必要があります。/Pages/demo-pagename/main.cshtml.cs ファイルのコードのRedirectToPageメソッドの引数の値を変更します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RedirectPage.Pages.wrong_demo
{
public class IndexModel : PageModel
{
public void OnGet()
{
}
public IActionResult OnPost()
{
return RedirectToPage("/demo-pagename/dest");
}
}
}
(アプリケーションルート)/demo-pagename/main
を開きます。ページが表示され、サブミットボタンが表示されます。[POST]ボタンをクリックします。
ボタンをクリックすると、リダイレクト先のページが表示されます。RedirectToPage() メソッドにはページの名前である "/demo-pagename/dest" を与えていますが、
リダイレクト先のURLは(アプリケーションルート)/results/destination
になっており、dest.cshtml に設定した @page ディレクティブで指定したURLに
正しくリダイレクトされます。
リダイレクト先をページの名前ではなくURLで設定したい場合は、RedirectToPage メソッドではなく、Redirect メソッドを利用します。
/Pages/demo-pagename/main.cshtml.cs ファイルのコードを下記に変更します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RedirectPage.Pages.wrong_demo
{
public class IndexModel : PageModel
{
public void OnGet()
{
}
public IActionResult OnPost()
{
return Redirect("/results/destination");
}
}
}
上記のコードに変更後プロジェクトを実行します。
(アプリケーションルート)/demo-pagename/main
を開きます。ページが表示され、サブミットボタンが表示されます。
ボタンをクリックすると、リダイレクト先のページが表示されます。Redirect メソッドに設定したURLにリダイレクトされることが確認できます。