要求に一致する複数のアクションが見つかりましたの解決法（ASP.NET）

# 背景
- ASP.NETを用いて、APIの開発（勉強）をしていた。
- 複数のアクションを定義して、勉強していたところ、あるアクションを実行しようとするとエラーが発生した。
- 解決に時間を要してしまったため、記事に残しました。

# 実際のエラーコード
```
https://localhost:44325/api/helloworld/testaction?text=aaa
```
上記へアクセスした結果、想定していない結果が以下のように出力された。
```
{"Message":"エラーが発生しました。","ExceptionMessage":"要求に一致する複数のアクションが見つかりました: \r\n型 WebAPITest.Controllers.HelloWorldController の GetMessage2\r\n型 WebAPITest.Controllers.HelloWorldController の TestAction","ExceptionType":"System.InvalidOperationException","StackTrace":"   場所 System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n   場所 System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n   場所 System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"}
```

# 実際のコード

```VB
Imports System.Collections.ObjectModel
Imports System.Data.SqlClient
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http

Namespace Controllers
    Public Class HelloWorldController
        Inherits ApiController

        <HttpGet>
        Public Function GetMessage() As String
            Return "Hello World"
        End Function
   
        <HttpGet>
        Public Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
            Return a + b
        End Function

        <HttpGet>
        Public Function GetMessage2(ByVal text As String) As String
            Return "Hello Word " & text
        End Function

        <HttpGet>
        Public Function TestAction(ByVal text As String) As (Integer, String) #このアクションを実行しようとしている
            Dim number As Integer = 1
            Dim message As String = "bbb " & text
            Return (number, message)
        End Function
    End Class
End Namespace
```

# 解決した手順
## 原因：複数のアクションが実行されていた
なぜか、複数のアクションが同時に実行されたことで、エラーが発生しているようだった。
```
<HttpGet>
```
私はこれをアクションの手前に定義することで、自動でルーティングが行われるものと勘違いしていたようだった。適切なルートパターンを定義しておく必要があった。

## 対処法：ルーティングを明示
```VB
<Route("api/helloworld/アクション名")>
```
これをもとに、ルーティングを明示してやることで解決しました。

```VB
Imports System.Collections.ObjectModel
Imports System.Data.SqlClient
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http

Namespace Controllers
    Public Class HelloWorldController
        Inherits ApiController

        <HttpGet>
        Public Function GetMessage() As String
            Return "Hello World"
        End Function
 
        <HttpGet>
        <Route("api/helloworld/Add")>
        Public Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
            Return a + b
        End Function

        <HttpGet>
        <Route("api/helloworld/GetMessage2")>
        Public Function GetMessage2(ByVal text As String) As String
            Return "Hello Word " & text
        End Function

        <HttpGet>
        <Route("api/helloworld/TestAction")>
        Public Function TestAction(ByVal text As String) As (Integer, String)
            Dim number As Integer = 1
            Dim message As String = "bbb " & text
            Return (number, message)
        End Function
    End Class
End Namespace
```

## 実行結果
```
https://localhost:44325/api/helloworld/testaction?text=aaa
```
上記へアクセスした結果、想定した結果を出力することができた。
```
{"Item1":1,"Item2":"bbb aaa"}
```

# 注意事項
- この記事では、visual studio 2022を使用しているので、試してみたい方は事前に準備が必要です。

# この記事は誰向けの記事か？
- 試しにASP.NETを始めてみたいと思っている人

# 環境
- OS：Windows10
- [visual studio 2022](https://visualstudio.microsoft.com/ja/vs/)
- [Visual Studio Community Edition](https://visualstudio.microsoft.com/ja/downloads/)

# 本記事における注意事項
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。