---
# System prepended metadata

title: ASP.NET Core `AddDefaultIdentity` を使用したアカウントの確認時に「No page named '/Index' matches the supplied values.」が発生する 2023-06-23
tags: [ログイン, Blazor Server, 例外, AddDefaultIdentity, SendGrid, Identity, ASP.NET Core, Blazor]

---

---
lang: ja-jp
breaks: true
---
# ASP.NET Core `AddDefaultIdentity` を使用したアカウントの確認時に「No page named '/Index' matches the supplied values.」が発生する 2023-06-23

![](https://hackmd.io/_uploads/rJoDVKzuh.png)

```shell=
An unhandled exception occurred while processing the request.
InvalidOperationException: No page named '/Index' matches the supplied values.
Microsoft.AspNetCore.Mvc.Infrastructure.RedirectToPageResultExecutor.ExecuteAsync(ActionContext context, RedirectToPageResult result)
```

```shell=
InvalidOperationException: No page named '/Index' matches the supplied values.
Microsoft.AspNetCore.Mvc.Infrastructure.RedirectToPageResultExecutor.ExecuteAsync(ActionContext context, RedirectToPageResult result)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilterAsync<TFilter, TFilterAsync>()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
```

```shell=
Show raw exception details
System.InvalidOperationException: No page named '/Index' matches the supplied values.
   at Microsoft.AspNetCore.Mvc.Infrastructure.RedirectToPageResultExecutor.ExecuteAsync(ActionContext context, RedirectToPageResult result)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
```

## 発生環境

* Visual Studio 2022
* Blazor Server
* スキャフォールディングは一切行っていない状態
* メール送信にSendGridを使用

## 発生状況

メール確認の本文にあるリンクをクリックすると発生する。
![](https://hackmd.io/_uploads/rk5sBFzd3.png)


## 参考資料

> RegisterConfirmation failing
> https://learn.microsoft.com/en-us/answers/questions/1254239/registerconfirmation-failing

## 調査

### `ConfirmEmail`をスキャフォールディングし、デバッグ実行

![](https://hackmd.io/_uploads/B1_bsFG_3.png)

`userID`には値が入っているが、`code`が`null`となっていることで発生していた。
![](https://hackmd.io/_uploads/HkK1CKGOn.png)

### `Confirm your email`の本文にある`a`タグのURL中の`&`がエンコードされて`&amp;`となっていることで`code`が取得出来なかった模様

```
Please confirm your account by <a href='https://localhost:7199/Identity/Account/ConfirmEmail?userId=1f19a918-5154-49ce-aaf7-0721b2ef0564&amp;code=Q2ZESjhLek1mczlxcDROS253Z2U4K05QS1NZbWRsY0N1SytNUTFIQ01QU24veWJNSHE1THg4SlVodzZibWlRbXNCMUlhamFBUGc0dFUvZWNTcDdNSTF6dlplYTMzUW9TZWRJUm5PclJsWi9wam13UWhaM3dXRzA2UVRXb0owUllTSDNDRFZndkFzU2M0MVpLdG5GRkdGMlBhZXpUUm0wcDBpUEZLa2U0dUJGTU10Yy9vbDQvS0QrbmpVVFBLcFgyVVVCUi9nbGNkNUtKQzd0U1hYRS9LckhJNkVab3VMMXJtbXZuMkxLS054VEpPOWxMR05HeXN6ejdkaEtrNTZkMWFQb0xXQT09&amp;returnUrl=%2F'>clicking here</a>.
```

トラブルの元となる為、HTMLメールは送信しないほうがよさそう。。。スマホからだとHTMLメールの方が便利か。。。

### 該当のソースコード

> src/Identity/UI/src/Areas/Identity/Pages/V5/Account/Register.cshtml.cs
> https://github.com/dotnet/aspnetcore/blob/da8a6f0766d1f333cc2faec72f97751e3c605dac/src/Identity/UI/src/Areas/Identity/Pages/V5/Account/Register.cshtml.cs#L149C20-L149C20

:::info
`HtmlEncoder.Default.Encode`されている。
:::


![](https://hackmd.io/_uploads/S11ra6M_2.png)


### 一時しのぎの対応

メール送信部分で、メール本文をHTMLデコードすることでとりあえずは動作する。

```csharp=
public class EmailSender : IEmailSender
{
    private readonly ILogger _logger;

    public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor,
                       ILogger<EmailSender> logger)
    {
        Options = optionsAccessor.Value;
        _logger = logger;
    }

    public AuthMessageSenderOptions Options { get; } //Set with Secret Manager.

    public async Task SendEmailAsync(
        string toEmail,
        string subject,
        string message
        )
    {
        if (string.IsNullOrEmpty(Options.SendGridKey))
        {
            throw new Exception("Null SendGridKey");
        }
        await Execute(Options.SendGridKey, subject, message, toEmail);
    }

    public async Task Execute(
        string apiKey,
        string subject,
        string message,
        string toEmail
        )
    {
        var client = new SendGridClient(apiKey);

        var from = new EmailAddress(
            Options.FromEmail,
            Options.FromEmailName
            );

        var to = new EmailAddress(toEmail, "");

        // 確認用のURLに `&amp;` が含まれるのでデコードする。
        var plainTextContent = HttpUtility.HtmlDecode(message);

        _logger.LogInformation($"[{subject}]");
        _logger.LogInformation($"[{plainTextContent}]");

        // HTMLメールはそのまま
        string htmlContent = message;

        SendGridMessage msg = MailHelper.CreateSingleEmail(
            from,
            to,
            subject,
            plainTextContent,
            htmlContent
            );

        // Disable click tracking.
        // See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
        msg.SetClickTracking(false, false);

        var response = await client.SendEmailAsync(msg);

        _logger.LogInformation(response.IsSuccessStatusCode
                               ? $"Email to {toEmail} queued successfully!"
                               : $"Failure Email to {toEmail}");
    }
}
```