やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

C#でHTTPリクエストできなかった(dotnet5)

 久しぶりにC#を触りたかったのでやってみたがダメだった。

成果物

前提

$ dotnet --version
5.0.102

手順

プロジェクト作成

mkdir hello_dotnet
cd hello_dotnet
dotnet new console

コード作成

Program.cs

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
using System.Text;
namespace hello_dotnet
{
    class Program
    {
        static readonly HttpClient client = new HttpClient();
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            HttpResponseMessage response = await client.GetAsync("https://www.google.co.jp/");
            response.EnsureSuccessStatusCode();
            string responseBody = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responseBody);
            /*
            using (var sr = new StreamReader(await response.Content.ReadAsStreamAsync(), Encoding.GetEncoding("Shift_JIS")))
            {
                string s = sr.ReadToEnd();
                Console.WriteLine(s);
            }
            */
        }
    }
}

実行

dotnet run

結果

 エラーが出た。

Hello World!
Unhandled exception. System.InvalidOperationException: The character set provided in ContentType is invalid. Cannot read content as string using an invalid character set.
 ---> System.ArgumentException: 'Shift_JIS' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. (Parameter 'name')
   at System.Text.EncodingTable.InternalGetCodePageFromName(String name)
   at System.Text.EncodingTable.GetCodePageFromName(String name)
   at System.Text.Encoding.GetEncoding(String name)
   at System.Net.Http.HttpContent.ReadBufferAsString(ArraySegment`1 buffer, HttpContentHeaders headers)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpContent.ReadBufferAsString(ArraySegment`1 buffer, HttpContentHeaders headers)
   at System.Net.Http.HttpContent.ReadBufferedContentAsString()
   at System.Net.Http.HttpContent.<>c.<ReadAsStringAsync>b__36_0(HttpContent s)
   at System.Net.Http.HttpContent.WaitAndReturnAsync[TState,TResult](Task waitTask, TState state, Func`2 returnFunc)
   at hello_dotnet.Program.Main(String[] args) in /tmp/work/hello_dotnet/Program.cs:line 17
   at hello_dotnet.Program.<Main>(String[] args)

 Shift_JISだと? はぁ? だれがそんなクソコード使うかよボケ。

 ははーん、さてはC#を作っているゴミクソMicrosoftの仕業だな? まーたお前かよ。もう嫌だ! せっかくWindowsを離れてShift-JIS地獄から抜け出したと思ったのに! もうShift-JISという言葉さえ見たくなかったのに! 死ねよマジで。Microsoftと共に滅べ! バルス

 もうMicrosoftの呪縛から抜けたと思ったのに! dotnet5だってOS依存から脱却したって言ってたのに! 嘘つき! Microsoftの嘘つき!

 ググっても解決できなかった。助けて。

C#におけるHTTPの混沌具合がヤバイ

 色々調べてみると、時代と共にHTTPリクエストの手法が変わってきている。

 こうやって振り回され続けてきたという事実。怒りと憎しみが募ってゆく。

 でも文句を言ってもはじまらない。仕方ないので勉強しなおそう。こうして学習コストがかさみ、やがてすぐに使えなくなっていく。これがいつものMicrosoftのやり口。ああ嫌だ嫌だ。

IHttpClientFactory

 IHttpClientFactoryについては内部でHttpClientを使っているっぽい。HttpClientにはパフォーマンス上の罠があるので、それをうまいこと回避したりしてくれるっぽい。

 以下MSDNをみてみたが、さっぱりわからんかった。あいかわらずMSDNはクソ💩。

 もう最初のコードpublic class Startupからしてわからん。たぶんASP.NETの作法なんだろうけどさ。え、まさかASP.NETでないと使えないの? だってフレームワークらしきConfigureServicesメソッドの引数IServiceCollectionAddHttpClientを呼び出すことで使えるって言ってるし。

 いやいや、私はふつうにコンソールアプリで使いたいんですが。どうしたらいいのさ。書いてない。さすがMSDNクオリティ。

 IHttpClientFactoryの使い方がわからない。とりあえず放置しよう。さようなら。

System.Net.Http.HttpClient

 今も使われているC#の標準的なHTTPリクエストのやり方。なのに以下のような問題があるんですって。

 もうこれだけでC#触りたくなくなった。でも、我慢してもう少し続けよう。使えればいいんだよ。

 HttpClientなら簡単なはずだ。以下MSDNを参考に、エラーが出た所はググって先述のコードを書き上げた。

 しかし謎のエラー。

 死んで? マジで死んで?

所感

 もうC#触りたくなくなった。

 PythonでサクっとHTTPリクエストしていたが、C#になると動かせない。ここまで悪化していたかC#。もうMicrosoftのソフトウェアは触りたくない。Shift-JISなんてワード見たくない。二度とWindowsには戻らない。久しぶりにみたShift-JISに殺意を覚えた。ああ嫌だ嫌だ本当に消えてほしい。Microsoftへの憎しみが募っていく。はやく浄化しないと。

 こうなったら新たにプログラミング言語を勉強しよう。気になっていたRubyやるか。

対象環境

$ uname -a
Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux