お米 is ライス

C#やらUnityやらを勉強していて、これはメモっといたほうがええやろ、ということを書くつもりです

ASP.NET Core 3.0+RazorでHTMLを描画する関数を作る方法

@helperとかHtmlHelperとかIHtmlContentとかいろいろ惑わされたのだけど、次のようにするとよさそう。

hoge.razor

@{
    //Hogeを表示する関数を定義する
    public void Display(Hoge hoge)
    {
        <p>@hoge.Fuga</p>
    }
}

<p>Hello world</p>
<p>following is hoge list</p>
@{
    //定義した関数を使う側
    foreach(var hoge in hogeList)
    {
        Display(hoge);
    }
}

問題はこれをよそのrazorファイルから呼び出せるかだが、まあ大丈夫でしょう(まだ試してない)

この書き方は以下のgithubのissueに書いてあった。
github.com

プライバシーポリシー

なんか書けって言われた

当サイトに掲載されている広告について

当サイトでは、第三者配信の広告サービス(Googleアドセンス)を利用しています。
このような広告配信事業者は、ユーザーの興味に応じた商品やサービスの広告を表示するため、当サイトや他サイトへのアクセスに関する情報 『Cookie』(氏名、住所、メール アドレス、電話番号は含まれません) を使用することがあります。

当サイトが使用しているアクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。
このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。
このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

ASP.NET Core 3.0+Blazorで詰まったとこ

この記事の目的

ASP.NET Core 3.0とBlazorを使っていい感じのサーバーを作ろうとしているので気づいたことを適宜メモしていくための記事

コントローラークラスの作成

    [Route("api/[controller]")]
    [ApiController]
    public class HogeController : ControllerBase
    {
        private FugaContext Context { get; }
        public HogeController(FugaContext context)
        {
            Context = context;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Hoge>>> GetHoge()
        {
            return await Context.Hoges.ToListAsync();
        }
    }

コントローラークラスはこんな感じのやつ

Startup.csに

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

これが書いてあればhttps://localhost:99999/api/HogeとかでAPIにアクセスできる

選択したコードジェネレータを実行中にエラーが発生しました

Scaffolding failed to edit Startup class to register the new Context using Dependency Injection.
Make sure there is a Startup class and a ConfigureServices method and Configuration property in it.

Blazor(ASP.NET Core hosted)のプロジェクトを作ってサーバー側のプロジェクトに適当なコントローラーをスキャフォールディングしようとしたら怒られたエラー。

これはStartup.csクラスにConfigurationというプロパティが無いので怒られている。
どうやらこのへんのスキャフォールディングはパターンマッチ的なことがされていて、Startupクラスとかが正しい形でないと怒られるみたいだ。
幸い、Blazor(サーバーサイド)のプロジェクトを作るとConfigurationとかがちゃんと書かれたStartupクラスが吐かれるのでそれを参考にするとちゃんとスキャフォールディング(いちいち書くのめんどくさい……)できた。

Blazor(ASP.NET Core hosted)のこういうコードを

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.AddMvc().AddNewtonsoftJson();
        services.AddResponseCompression(opts =>
        {
            opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "application/octet-stream" });
        });
    }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseResponseCompression();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBlazorDebugging();
        }

        app.UseClientSideBlazorFiles<Client.Startup>();

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
            endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
        });
    }
}

下記のように書き直してやろう(ダジャレじゃないよ)

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

        // 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.AddMvc().AddNewtonsoftJson();
        services.AddResponseCompression(opts =>
        {
            opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "application/octet-stream" });
        });
    }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseResponseCompression();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBlazorDebugging();
        }

        app.UseClientSideBlazorFiles<Client.Startup>();

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
            endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
        });
    }
}

あくまで個人的な感想だが、最近のC#(というかASP.NETってそういうもんなのか?)はパターンマッチに傾倒しすぎてて、「型安全!」「安心!!」みたいなプログラマに優しい言語からだんだんと離れて行ってしまってるような気がしてう~~ん……。

データベースへのアクセス

何も考えずにコントローラーをスキャフォールディングすると、ついでに作るDbContextへのConnectionStringがappsettings.jsonに追加される。
このConnectionStringはいい感じのローカルSQLサーバーへの接続を表している。が、このままだとコントローラーへAPIで問い合わせてもSQLサーバーに入れませんでしたというエラーが出る。
なので初めにまずマイグレーションというやつをして、次にそのマイグレーションを使ってデータベースを初期化しないといけない。
それをするにはプロジェクトのディレクトリへ行き、Power shellとかで次のようなコマンドを打つ。

dotnet-ef migrations add initial-migration //多分、いい感じのマイグレーションをいい感じに生成する魔法の言葉
dotnet-ef database update          //多分、マイグレーションを使ったデータベースの初期化

ところでマイグレーションってなんだ……?

injection

テンプレートで生成されたrazorページの中を見ている「@injection hogehoge」というのがあった。
調べてみるとこれを使うことでStartup.csの中で登録したシングルトンにアクセスできるらしい。
詳しくは
ASP.NET Core でのビューへの依存関係の挿入 | Microsoft Docs
とか
ASP.NET Core MVC を使ってドロップダウンリストをいい感じに実装する - しばやん雑記
とか。

とにかく
Startup.csに

public void ConfigureServices(IServiceCollection services)
{
    ~~
    services.AddSingleton<HogeSingleton>();
    ~~
}

と書いておけば

@injection HogeSingleton hogeSingleton

みたいにしてrazorファイルからアクセスできる。

Html.DisplayFor、Html.EditorFor

あるインスタンスをいい感じに編集できるような機能はないかなあと思っていたところ、これまたテンプレートで「Entity Frameworkを使用するRazorページ(CRUD)」を作ってみたらIndex.cshtmlの中に書いてあった。
DisplayForはその名の通りそのインスタンスをいい感じに表示する関数で、EditorForはそれが編集できるようになってるもの。
クラスのプロパティとかにアトリビュートで[DisplayName("hogehoge")]とか書けばある程度は指定もできるみたいだ。
このページが詳しい。
第6回 テンプレート機能でビュー開発を効率化(1/3) - @IT


ASP.NET Core 3.0のプレビュー版でmigrationしようとしたらうまくいかなかったときの対処法

現象

dotnet-ef migrations add initial-migration

このmigration用のコマンドを実行しようとするとこんなことを言われる

The application to execute does not exist: 'hogehoge\.dotnet\tools\.store\dotnet-ef\2.2.4-servicing-10062\dotnet-ef\2.2.4-servicing-10062\tools\netcoreapp2.2\any\dotnet-ef.dll'.

原因はCore 3.0で実行してるのにEntityFrameworkのCore 2.2のほうを実行しようとしてるから(だと思う)

対処法

古いほうをアンインストールしてからCore3.0版をインストールする

dotnet tool uninstall dotnet-ef --global
dotnet tool install --global dotnet-ef --version 3.0.0-*


今年の目標

  • 神社へいっぱい行く
  • SRPGをいいとこまで持っていく
  • 曲をいっぱい作る
  • 今まで作った曲に歌詞をつけてあげてちゃんと公開する
  • 女性に慣れる
  • お絵かきの練習をする
  • 小説を書く
  • ゲームをいっぱいする
  • アニメをちょっとでも見る
  • 早起きをして普通の生活をする
  • 美味しいものをいっぱい食べる
  • 楽しいことをいっぱいする

UnityのCoroutine的なものを自前で実装する

Coroutine

コルーチンはこんな感じで使えるやつだ

void Awake()
{
    StartCoroutine(Test());
}

IEnumerator Test1()
{
    DoSomething();
    yield return null;
    Hoge();
    yield break;
}

コルーチンのネストもできて

void Awake()
{
    StartCoroutine(Test2())
}

IEnumerator Test2()
{
    Debug.Log("1");
    yield return null; 
    Debug.Log("2");
    yield return StartCoroutine(Test3())
    Debug.Log("3");
    yield break;
}

IEnumerator Test3()
{
    Debug.Log("A");
    yield return null;
    Debug.Log("B");
    yield break;
}

こんな感じにすると1, 2, A, B, 3の順で出力される(たぶん)。

Coroutineの問題点

この記事の目的はあくまで「実装してみよう!!」というものであり問題点を指摘することが目的ではないが、実装への動機づけのために言及しておく。

イテレータから何が返ってくるかわからな

イテレータをネストしているとき、つまりTest2関数の中でTest3関数を呼んでいるようなことをしているときの話である。
例えばTest3の中でのある処理が成功したか失敗したかをTest2で知る必要があったとしよう。
それを知るにはTest3の最後にyield return falseなどとしてやればよい。
しかしさらにTest3の中からさらにTest4へとネストしたい場合、yield return StartCoroutine(Test4())ともしてやらなければならない。
こうなった場合、関数の返り値の型をIEnumerator<bool>などと指定することは不可能となり、単にIEnumeratorと書かなければならなくなる。
そうするともはやイテレータから何が返ってくるのかがわからなくなり、あるいは無法地帯のような状況になってしまうかもしれない。
そうならないためにも、UnityにおけるCoroutineのようなものを自前で用意しようということなのである。

実装

というわけで、自前で実装してみたのがこちらになります。 gist.github.com

こうしておくとイテレータが何返してくるのかわかって安心だよねーという話でした。
意外と簡単に実装できますね。

使い方

こんな感じで使うよー\(^o^)/

private Iterator iterator;
private bool flag = false;

void Awake()
{
    iterator = new Iterator();
}

void Update()
{
    iterator.Progress();
}

IEnumerator<IteratorResult> Hoge()
{
    yield return IteratorResult.Continue;
    yield return IteratorResult.Nest(Fuga());
    yield return IteratorResult.Completed;
}

IEnumerator<IteratorResult> Fuga()
{
    yield return IteratorResult.Continue;
    if(!flag)
    {
        yield return IteratorResult.Canceled;
        yield break;
    }
    
    yield return IteratorResult.Completed;
}

まとめ

UnityのCoroutineを自前で実装してみたよ! 他にいい方法があったら教えてくり!!

鵜飼さんをたどって

ここで一句

このブログ、ソースはほとんどウィキペディア

鵜飼さんとは

これまで記紀に関する調べ物をしていて気になっていたことがあります。
それは、何らかの(戦闘と関係があるとは思えない)職掌を持っている人たちがやたらと出てきて活躍することです。
その中でも顕著だと思ったのが、神武東征神話の中に登場する"久米歌"といわれる何編かの長歌です。
この歌は第二次世界大戦の折に戦意高揚のため使われた「撃ちてしやまむ」という言葉のもととなっている歌であり、「敵を打ち負かしてやろう!!」という心意気のこもった歌となっています。
しかし、山椒の実で口をヒリヒリさせたり、韮の芽を根っこから引き抜いていたりと、およそ戦っているとは思えないような比喩が頻繁に使われています。
というのも、昔は戦闘を生業にする人々などほとんど存在せず、普段は農業や漁業によって生計を立てていた人々がいざというときに戦っていたからで、そういった人々の活躍を表現するためにこのような比喩が使われたのでしょう。
したがって、この比喩の部分を注意深く見てやることでどこの誰がその時に活躍したのかということが見えてきそうです。

さて、そこで久米歌の一つ、

楯並めて 伊那佐の山のこの間よも い行きまもらひ戦へば
吾はや飢ぬ 島つ鳥鵜養が伴 今助けに来ね
<現代語訳>
楯を並べて伊那佐の山の木の間を通って行きながら、敵の様子を見守って戦ったので、
我々は腹がへった。鵜養部の者どもよ、今すぐ助けに来てくれ。

http://amanokuni.blue.coocan.jp/kumeuta.htmより)

という歌に注目してみます。
この歌では伊那佐という山で戦っているときに鵜飼部という人たちに助けを求めています。
ここから、久米氏という宇治族のうち鵜飼部というおそらくは鵜飼を生業としていた人々が伊那佐という土地に住んでいたことがわかります。
鵜飼とは文字通り鵜(う)という鳥を飼っている人々のことで、鵜を操って魚を捕ることから、「腹が減った」といって助けを求めるのもうなずけます。
あとは伊那佐がどこなのか、ということですが、奈良県宇陀市に伊那佐村があるとのこと(伊那佐村 - Wikipedia)なのでおそらくここのことでしょう。

久米氏について

ここで久米氏という人々について少し説明しておきます。
久米氏については久米氏・山部氏が詳しいのですが、もともと九州のほうにいた人々で主に漁業を生業としていた海の民です。
熊本県の"クマ"、球磨川の"クマ"、熊襲の"クマ"という音と久米氏との関係も気になります。
というのも、古代における日本語では母音が変わっても同じ言葉、あるいは近しい言葉であることがままあります。つまり"クマ"と"クメ"も変化しうるのです。
この「k〇m〇」という言葉に注目していると熊野大社の"クマ"や上賀茂神社下鴨神社の"カモ"、はたまた神の"カミ"など、さまざまな言葉との関係を疑えて楽しいです。

鵜飼さんの出身地

記紀の別の記述によると、

梁を作つて魚を取る者有り、天皇これを問ふ。対へて曰く、臣はこれ苞苴擔の子と、此れ即ち阿太の養鵜部の始祖なり

鵜飼い - Wikipediaより)

ということで、阿太という(おそらくは)地名とも関係があることがわかります。("アダ"という音を聞くと宇陀市の"ウダ"という音との関係を疑いたくなってしまいます)
この"アダ"という地名ですが、別の神話においても登場します。
天孫降臨神話においてニニギがコノハナサクヤヒメと結婚をするのが阿多というところであり、引用元によればそれは薩摩半島西南部を広く表した地名であったということです。
inakaseikatsu.blogspot.jp
これらの"アダ"が同源であるとするならば、鵜飼さんは古くは九州地方でも活躍していたと捉えることができるのではないでしょうか。

神功皇后と鵜飼さん

神武東征の話において活躍する鵜飼さんですが、神功皇后とも少なからず関係をもっています。
というのも、三韓征伐の際に使用した船を和歌山県和歌山市にある紀三所神社(志磨神社・静火神社・伊達神社)という場所に祀ったという話があります。そしてWikpediaによると静火神社の神官は鵜飼さんが務めていたのだそうです。
この紀三所神社の近くには日前(ひの"クマ")神社や竈山("カマ"やま)神社などといった神社が存在しており、先に述べたロジックにより久米氏との関係もあるのではないかと思います。ということはこの鵜飼さんも久米氏の鵜飼さんなのではないでしょうか。
なぜ三韓征伐で用いた船をわざわざ紀伊の国までもっていったのか、なぜ鵜飼さんを神官としたのか、という疑問とともにこの話を再解釈するとかなり素直に次のようになるかと思われます。

神功皇后は海の民である久米氏の協力を大いに受け、三韓征伐に成功した。この久米氏の中には阿多からやってきていた鵜飼部も含まれていた。
三韓征伐ののち、大和入りの際にも神功皇后は久米氏に協力を仰ぎ、鵜飼部もこれに従った。
瀬戸内海を渡り畿内にたどり着いた神功皇后は紀の国をも掌握し、三韓征伐や大和入りなど諸々の功を労って鵜飼氏に紀三所神社周辺の土地を治めさせた。

ちなみに紀三所神社にほど近い海岸沿いにはこれまた神功皇后が祀ったことが始まりとされる淡嶋神社があります。

鵜飼さんをたどって

こうなってくると、神武東征に出てくる鵜飼さんと神功皇后により神官の地位を与えられた鵜飼さんとを繋げてみたくなってくるのが人情というものでしょう。
というわけで、奈良県宇陀市にある伊那佐村と和歌山県和歌山市にある静火神社とをグーグルマップで確認してみましょう。すると意外にも容易く両者を繋げることが可能であるとわかります。
www.google.com
そうです、JR和歌山線が通っています。という冗談はさておき、紀ノ川の上流と下流にそれぞれ位置していることがわかります。この紀ノ川のおかげで静火神社のある和歌山市から伊那佐村の手前となる五條市までは低地となっており、そのため交通が盛んであったのは想像に難くありません。また、古代においては河川を使った水路も非常に重要な交通手段であったので、紀ノ川を通じて往来があったのはもはや明確と言ってもいいでしょう。
つまり、紀三所神社周辺を与えられた鵜飼さんが紀ノ川を遡り内陸へと移住していったのが伊那佐村の鵜飼さんなのではないでしょうか?
あるいはもともと紀ノ川沿いを支配していた鵜飼さんに神功皇后が協力を仰ぎ、その見返りとして紀三所神社周辺の支配権の正当性を認められたというストーリーも考えられます。
この考えを補強するかのように、中間地点である奈良県五條市には阿田という地名が今でも残っています。

まとめ

神武東征における鵜飼さんと、神功皇后の大和入りにおける鵜飼さんとは元をたどれば同じ氏族であり、九州から紀三所神社周辺に移住したのち、紀ノ川沿いに伊那佐村周辺に展開していったのではないか。
この考えが正しいかを見極めるため、これら2点を結ぶ線上に存在する地名や神社、遺跡などの総合的な分析を今後の課題とする。