VisualStudioで、iOSアプリ(MAUI)+ASP.NET Coreのローカルデバッグ環境構築でハマりまくった件(解決策あり）

# はじめに
皆さんこんにちは、Kazuyaです。

今、絶賛MAUIプロジェクトを作成中なのですが、
Azure AAD B2C認証を実装したモバイルアプリケーションからだと、
CosmosDBの認証フローはトークンベースではできないことが分かり、
中間ASP.NET Coreサイトを作成して、そこを経由してからアクセスする仕組みにしようかと思いました。

ちなみに、ASP.NET Coreサイトを中継して、iOSアプリからAzure側にアクセスする仕組みは以下を参照して作りました。

https://learn.microsoft.com/ja-jp/azure/developer/mobile-apps/azure-mobile-apps/quickstarts/maui/?pivots=vs2022-mac

ここでいろいろとページを見ていたのですが、ローカル環境構築の手順通りやっても、
2023/5/15時点では、はまりにはまり以下のようなエラーが、iOS側から。

    1. Connection refused: localhost:7198
    2. Connection timeout: 192.168.x.x:7198
    3. SSL Connection error: 192.168.x.x:7198


調べていくと、これらは以下のような要因。
    
    1. 端的に、「localhost」だとうまくいかなさそう。公式では、iosシミュレーターは、ホストOSとネットワークを共有するはずなんだけど、環境依存していそう
    2. IPに変更してアクセスするようにしてみたものの、タイムアウトエラー
    3. いろいろやってみた後の、エラー。

実際、CosmosDBに対するアクセスをそこまで強固にする必要性があるのかというと微妙なラインではあります。
ただ、セキュアな環境を今後構築する必要が出た場合や、これに限らず、SQLServerだったとしても、
このルートを党せるようになっていないとつらいな・・・と。


というところで、いろいろ踏ん張って調べに調べてうまく言った方法を以下に紹介

# 事前に環境だけ整理
・Visual Studio 2022
・.NET 7(Maui/ASP.NET)


# 解決策
## 1. ASP.NET Core サイトの設定
デフォルトでは、デベロッパー用のIIS Expressではなくインスタントサーバーが起動するようになっている。
ので、デバッグ起動プロファイルUIを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/6b1a8832-54a4-19ba-f41a-954ce04d9b91.png)

アプリのURLを以下のように、「localhost」ではなく、自分の端末のローカルIPアドレスにする。
**注意：この時、このWindows端末のローカルIPに、iOSシミュレーターが起動するビルド用のMac端末から、pingが通ることを確認しておく**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/a3fc0631-2f2e-177c-7fbc-40caf4932720.png)

同じウィンドウの下のほうにある、「アプリの SSL URL」を調べておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/eff83206-7222-933c-e752-8d64ffc1fe39.png)

これでOK。

## 2. MVVMをつかさどる中間プロジェクトのWebサーバーURL指定
この例では、TodoAppを使っているので、TodoApp.Dataプロジェクトにある、「Constants.cs」を開く。
この「Constants.cs」に、上記で記載している公式ページ通りの作成したASP.net coreサイトの時は、Azureにデプロイした後のURLを入れているが、上記「１」で取得したSSL URLを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/1da1539d-b7b1-996b-99f2-b3268781ddc7.png)

これでOK。

## 2. SSL認証をスキップさせるための、UnSecureHttpHandlerを作成
ローカルで実行している場合、SSL証明書が向こうのエラーが出ることがある。
ローカルで実行しているとき、SSL証明書を無視したい。

そこで、スキップするための方法をし調べると「HttpClientHandler」の「ServerCertificateCustomValidationCallback」を使ってスキップできることが分かる。

が、しかし。
このサンプルプロジェクトで使われている「HttpMessageHandler」を継承した「LoggingHandler」では、HttpClientHandlerのような、「ServerCertificateCustomValidationCallback」が実装されていない。

ただし、「SendAsync」を実装しているので、その中で利用するhandlerを、自作したhandlerに変えてしまうことで、これが実現できる。
以下、「LogginHandler.cs」に含まれている処理の例。

```csharp:LoggingHandler.cs


    public class CustomeValidationHandler : HttpMessageHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var handler = new CustomHttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => {
                    return true;
                }
            };
            return handler.SendAsyncEx(request, cancellationToken);
        }
    }

    public class CustomHttpClientHandler : HttpClientHandler
    {
        public Task<HttpResponseMessage> SendAsyncEx(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return this.SendAsync(request, cancellationToken);
        }
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken);
        }
    }

    public class LoggingHandler : CustomeValidationHandler
    {
~以降は変更しない

```

これで、SendAsyncが呼ばれると、
```csharp

                ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => {
                    return true;
```
の部分が応答してくれて、SSL証明書妥当性チェックがスキップされる。

これでOK。

最後にMAUI側と言いたいところですが、MAUI側は特に不要。

# デバッグ実行

ここはサーバー呼び出し前だけど・・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/77094aa1-25d2-b92e-c119-8042ac5e1e8f.png)

ここはサーバーのSSL証明書検証までたどり着いてうまくいく！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/e3cf13bd-eb88-2f92-1328-06e620614c6b.png)

で、サーバー側は、MVVMだとブレークが止まらないのでサーバーにうまくつながっているのかわかりづらいのだけど、コントローラーのコンストラクタとかで止めておけば止まる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/1ec97eed-2242-3b94-9274-b4e6559cabe6.png)

## うん。うん。いいね！！！！  ##


# おわりに
今回はデバッグ技術的な話ですが、やはりASP.NET coreの開発をするときに連携元からの一連のデバッグができないと、VisualStudioを使っている価値が下がり気味なので、こちらはしっかりできるように押さえておきたいですね👍

誰かのお役に立てばと思いますー

次は現在開発している、Azure + MAUI + OpenAI + Cognitive Serviceあたりをまとめようと思います👍

それではまた会いましょう👍

# 免責事項
本記事は、著者が独自で調査・検証を行った内容で、所属企業やいずれかの企業の公式見解に基づきません。
また、本記事を参考にして行った作業に関して発生するすべての損害、問題、課題について、当方では一切の責任を負えませんのであらかじめご了承ください。