log 2019/08/27

Fix link (#14013) · aspnet/AspNetCore.Docs@611d4b0 · GitHub

以下の tutorial へのリンクの修正

Razor Pages with Entity Framework Core in ASP.NET Core - Tutorial 1 of 8 | Microsoft Docs


Add connect command, remove set swagger command (#13973) · aspnet/AspNetCore.Docs@89babd8 · GitHub

以下のページの修正。(日本語版はまだ来てない)

Test web APIs with the HTTP REPL | Microsoft Docs

知らなかったが HttpRepl という global tool がある。

github.com


Update Authorization Section (#14024) · aspnet/AspNetCore.Docs@443289f · GitHub

以下の 2.2 to 3.0 の migration ドキュメントの Authorization 部分の修正。

Migrate from ASP.NET Core 2.2 to 3.0 Preview | Microsoft Docs

PR の方を見ると以下のような説明。

Describe the differences between DefaultPolicy and FallbackPolicy, their relationship with [Authorize] and IEndpointConventionBuilder.RequireAuthoriztion(). Previously, the docs suggested app.UseAuthorization(new AuthorizationPolicyBuilder().Build())); which is an overload that no longer exists.

ドキュメントの内容としては

  • AuthorizeFilter を使った場合は services. AddAuthorization で policy の設定をすることを推奨
  • DefaultPolicy と FallbackPolicy` がある
  • どちらも AuthorizationPolicyBuilder でカスタマイズできる
  • FallbackPolicyDefaultPolicy を含む他の plicy が設定されていない時に発動する

LoggerMessage updates for 3.0 (#14021) · aspnet/AspNetCore.Docs@a68e43d · GitHub

以下の LoggerMessage のドキュメントの大幅加筆。

High-performance logging with LoggerMessage in ASP.NET Core | Microsoft Docs

ちょっとボリュームが多いので、またじっくり読む。


Angular-CSharp template variable naming (#13423) · aspnet/AspNetCore@a881804 · GitHub

テンプレートの Controller の変数名の修正


File Providers topic update for 3.0 (#14027) · aspnet/AspNetCore.Docs@2d27dd6 · GitHub

以下の File Provider に関するドキュメントの修正

File Providers in ASP.NET Core | Microsoft Docs

File Provider の用途や仕組みはさらっとしか分かってなかったが、良さそうなドキュメント。

修正としては以下の PR の Description にある通り。

File Providers topic update for 3.0 by guardrex · Pull Request #14027 · aspnet/AspNetCore.Docs · GitHub


Mgbbs/hidden for checkbox render mode (#13014) · aspnet/AspNetCore@90e89e9 · GitHub

CheckBox 作成の Tag helper に CheckBoxHiddenInputRenderMode が追加された。 EnumNone, Inline, EndOfForm がある。

CheckBox にさらに Hidden の input (要は <input type="hidden" ) を追加するかどうか。

よくある、Checkbox はチェックが入っていないと form に送信されない問題に関するもの。


Correct capitalization of JavaScript in template site.js files (#13456) · aspnet/AspNetCore@a2178e5 · GitHub

Javascript -> JavaScript

log 2019/08/25

commits

Merge branch 'master' into merge/release/3.0-to-master · aspnet/EntityFrameworkCore@0b87c81 · GitHub

EntityFrameworkCore の mastermerge/release/3.0-to-master branch に merge 。

netcoreapp のバージョンは 3.0 じゃなく、5.0 が使われているのを初めて知った。

KnownAppHostPack, KnownFrameworkReference という見慣れないタグが使われているのが気になった。

以下あたりの PR で追加されている。


Merge branch 'release/3.0' => 'master' (#17408) · aspnet/EntityFrameworkCore@c3636f2 · GitHub

EntityFrameworkCore の release/3.0 branch が master に merge。

ただ、これは頻繁に行われているので、別にこれでリリースされるとかではない。

Merge branch 'release/3.0' into merge/release/3.0-preview9-to-release… · aspnet/EntityFrameworkCore@29eeb0c · GitHub

release/3.0 branch が merge/release/3.0-preview9-to-release/3.0 branch に merge。

いくつかの依存 package は preview9 から rc1 になっている。

Merge branch 'release/3.0-preview9' => 'release/3.0' (#17409) · aspnet/EntityFrameworkCore@3bf3d08 · GitHub

'release/3.0-preview9' branch が 'release/3.0' に merge。

Merge branch 'release/3.0' => 'master' (#17413) · aspnet/EntityFrameworkCore@7f30d52 · GitHub

release/3.0master に merge。


Merge branch 'master' into merge/release/3.0-to-master · aspnet/AspNetCore-Tooling@5d8aea3 · GitHub

AspNetCore-Tooling の mastermerge/release/3.0-to-master branch に merge 。

netcoreapp のバージョンは EF Core と同じく。

テストコードを見ていると、EF Core と AspNetCore-Tooling はどちらも Xunit を使っているが assertion lib に EF Core は FluentAssertion を使っているのが見て取れた。(全体的にかどうかは分からないが)


Merge branch 'release/3.0' => 'master' (#1014) · aspnet/AspNetCore-Tooling@dd8d708 · GitHub

AspNetCore-Tooling の release/3.0 branch が master に merge。

Merge branch 'release/3.0' into merge/release/3.0-preview9-to-release… · aspnet/AspNetCore-Tooling@457718a · GitHub

AspNetCore-Tooling の release/3.0 branch が merge/release/3.0-preview9-to-release/3.0 branch に merge。

いくつかの依存 package は preview9 から rc1 になっている。

Merge branch 'release/3.0-preview9' => 'release/3.0' (#1015) · aspnet/AspNetCore-Tooling@1ae4d7d · GitHub

で、今度は release/3.0-preview9 branch が master に merge。


Drop 'en-us' loc segment from URLs + doc nits (#13410) · aspnet/AspNetCore@460f9b6 · GitHub

ドキュメントの URL に不要な en-us セグメントが入っていたのを消したのと、些細なドキュメントの修正。

nits は些細な修正みたいな意味らしい。


Removed unnecessary explanation of view compilation in Areas. (#14001) · aspnet/AspNetCore.Docs@38236da · GitHub

以下の PR に対する修正。

Statement about View compilation is not correct · Issue #13895 · aspnet/AspNetCore.Docs · GitHub

Views のコンテンツがリクエストされるまでコンパイルされないというのは、少なくとも deploy される環境では正しくなく [projectname].Views.dll が生成されるはず、という issue が発端。

3.0 preview からは、以下の記事にあるように runtime compilation は opt-in になっている。

ASP.NET Core での Razor ファイルのコンパイル | Microsoft Docs

2.2、2.1 でも微妙に挙動が異なりますが、開発環境では true になるよう。

ASP.NET Core での Razor ファイルのコンパイル | Microsoft Docs

結局、このセクションでコンパイルに関して言及する必要無いのではというので削除された模様。


Slight rework of combining Sliding and Abs IMemoryCache expirations. … · aspnet/AspNetCore.Docs@39ac2c1 · GitHub

以下のドキュメントの話。

Cache in-memory in ASP.NET Core | Microsoft Docs

sliding expiration と absolute expiration についての部分で、手直しが行われている。

sliding expiration は指定された interval の間に request が無ければ cache から消えるが、逆にアクセスが頻繁にありすぎると、cache のデータが stale なものになる可能性が出てくる。
よって abosolute expiration と組み合わせて、一定時間で確実に cache から消える状態に(つまり上限の時間を決める)することで、鮮度を保てる。

確かに新しい文章の方が理解しやすい。

Salesforce の SOQL で MALFORMED_QUERY が出る

そもそも何か

http://developerforcejp.s3.amazonaws.com/developer/docs/soql_sosl/salesforce_soql_sosl.pdf
Force.com SOQL および SOSL リファレンス p.8

ステートメントの文字数制限―デフォルトでは、SOQL ステートメントの長さは 10,000 文字を超えることが
できません。SOQL クエリのステートメントの文字数制限を増加するパイロットプログラムが導入されます。
上限を (最大で 20,000 文字まで) 上げるには、salesforce.comの担当者までお問い合わせください。この最大長
を超える SOQL ステートメントでは、API は MALFORMED_QUERY 例外コードを返します。結果の行は返され
ません。

要は構築したクエリの長さによって発生するものらしい。ちなみに、私が遊んでいる環境では C# 用のライブラリを使用している。

違うケースでも発生した

参考:

上記のケースのようにクエリの中にシングルクォートが入っていると発生するケースがある。

私が試していて発生したケースもこれ。

そもそもパラメータバインディングとかないの?

どうやら C# 用は公式にはないらしい。どうりで。。

それでもエスケープはせねばならぬらしい

以下のドキュメントが出ていた。

まとめ

ドキュメント通りエスケープしろって事かな? Bell って何。。まあ、言ってもただ API にリクエスト投げてるだけのライブラリだし、ちゃんとやれって事か。

またいいねボタンで IE のアラートが出た件

発端

自社サービスのログイン画面には facebook のいいねボタンを置いています。タイプは以下のもの。

アイコンとリンクが付いているやつとでもいいましょうか。

突然

いつからかは正確には分かりませんが、IE8 以下の IE でログイン画面に行くと IE のセキュリティアラートが出るようになりました。
内容は セキュリティで保護された Web ページコンテンツのみを表示しますか?という内容で、以前に発生したものと全く同じでした。
このアラート自体は以前の調査で HTTPS の画面の中で HTTP の通信を行なっているものがあるためと分かっており、当時は いいねボタンの iframe の url を https に変更する事で事無きを得ました。

http://d.hatena.ne.jp/dany1468/20110627/1309172872

が、今回はパケットを見てみても http で通信しているやつなんかいない。現に IE のアラートで詰まっている読み込みも「https://www.facebook.com/images/spacer.gif」となっており、どう見ても https なのです。

ログイン画面という性質もありますし、何より IE8 のユーザも結構いるので心象も悪い。。

他のサイトはどうなの?

その前に

上記のサンプルで示した Facebook Developer の url で生成したいいねボタン (iframe) も、https の配下に置くとやはりアラートが発生しました。どうやら作り方うんぬんという訳ではなさそうです。

で他のサイト

いろいろ見てみましたが他のサイトは発生していなんですよね。まあ、単純に http のサイトが多いってのもありますが、https のサイトでも起きていない。例えば サイボウズ Live のサイトなんかも上段にいいねボタンはある訳ですが、https であるにも関わらず IE でアラートは出ません。

アレ?

デザインが違う。アイコンもページへのリンクもありません。単にいいねボタンと件数だけが出ているボタンです。確かにどこもそうなっている。

変えてみた

これまで配置していたのは「Like Box」というパーツだったのですが、どうやら他のサイトに配置されているのは「Like Button」という異なるパーツでした。

どうなった?

大丈夫になりました。確かにこのパーツなら https 環境に配置しても IE8 でアラートも出ませんでした。まあ、デザイン変わりすぎなので簡単に置き換えできいのですが。。

まとめ

結局原因の根本まではわからなかった訳で、IE の方が何か勘違いを起こしているのか、それともそもそも自社サービスの環境に何かミスがあったのか。謎です。

とはいえ、またこういう問題が起こったら、パーツを変えてみるというのもよいのではないでしょうか、という事ですね。

Task could not find "AL.exe" でエラーが出た時の対応

開発者の環境では出ないエラー

テスト用のビルドは本番とほぼ同様の環境で行うようにしているため、Visual Studio のような開発者が使う IDE はインストールせず、Jenkins から MSBuild を叩いてビルドするようにしています。
ですが、その環境の中で妙なエラーがでました。そして、そのエラーは IDE の入った開発者の PC では一切起きないものでした。

(GenerateSatelliteAssemblies target) ->
  c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets(2342
,9): error MSB3086: Task could not find "AL.exe" using the SdkToolsPath "" or t
he registry key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v
7.0A". Make sure the SdkToolsPath is set and the tool exists in the correct pro
cessor specific location under the SdkToolsPath and that the Microsoft Windows
SDK is installed

ちょうど Windows 環境での Git の改行コードを勝手に変更する問題で別のビルドエラーにも苦しんでいた状態だったので訳の分からないビルドエラーにかなーりイライラ。。

AL.exe とは何か?

AL.exe アセンプリ リンカー - MSDN
お恥ずかしながら正直初めて出会ったのですが、アセンブリマニフェストを含むファイルを作成できると書いてあります。まあ、いろいろ説明を斜め読みしていると、どうやらエラーになったビルドにはそのコミットから埋め込みのリソースファイルが入っている事が分かりました。表示文字列をリソースで入れ替えられるような対応をしていたので、おそらくその影響でかなーと。

そして、興味深い一文が。

このツールは Visual Studio および Windows SDK と一緒に自動的にインストールされます

IDE はおろか、Windows SDK も入ってねぇ。。なるほど、確かにエラーメッセージにも「Microsoft SDKs\Windows\v
7.0A」みたいな文字が並んでいます、おそらくそれをインストールすればOKという事でしょう。

Windows SDK を探す

さっそく Winodws SDK をダウンロードしようとしたものの、どうも v7.0A というのが見つからない。見つかるのは 7.1 なのです。

Microsoft Windows SDK for Windows 7 and .NET Framework 4

試しにダウンロード・インストールしてみましたが、エラーメッセージは一向に変わらず。。まあ、バージョン違いますもんね。

v7.0A とは

調べていくと、どうやら Visual Studio 2010 をインストールすると入る SDK のバージョンのようで、普通にインストールする事は難しそうでした。まあ、開発者の PC からディレクトリ毎コピーしてくるという手もあるのですが、どうもやり方として気に入らないので、事例を探しました。

v7.0A のレジストリを作ってしまう

いろいろ調べていると、てっとり早くは、やはり開発マシンから v7.0A を一式コピーしてくるというものでした。レジストリもインポートしてしまえば問題無さそうな事が書いてあります。

もっと簡単な方法は無いか?

私の目的は v7.0A 自体を使う事というよりは、要は AL.exe でビルドさえできればいい。つまり、v7.0A でも v7.1 でもいいのです。もちろん、それで問題が出れば v7.0A を使うしかないのだけれど、なんとか普通にダウンロードしてこれる v7.1 でビルドしたい。というか v7.0A をコピーしてくるのは IDE 依存な気がしていまいちだなーと。

v7.0A のレジストリを v7.1 に向けてしまえばいいのでは?

という事を思いつきました。ヒントは上述したリンクの2つ目の以下の部分でした。

I have found that if you only install Windows SDK 7.1 and .NET 4.0. MSBuild does not set proper paths to SDK40ToolsPath and SDK35ToolsPath. To fix it, I had to change a few entries in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0: "SDK40ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.1\\WinSDK-NetFx40Tools-x86@InstallationFolder)" Similarly change "v7.0A" to "v7.1" in SDK35ToolsPath and FrameworkSDKRoot

SDKToolsPath の向き先をレジストリレベルで変えてしまえば良いのではという提案です。
いろいろ試行錯誤していると、結果的に私の状況を改善するには、以下のレジストリの変更だけで十分である事がわかりました。

以下のキーを追加。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A

キーに対して以下のように文字列値を追加。

名前: InstallationFolder
データ: C:\ProgramFiles\Microsoft SDKs\Windows\v7.1\


おそらく他の SDK の機能を使うケースがあれば、v7.0A のレジストリをそのままインポートしてしまって、v7.1 に書き換えてしまう方が良いのかもしれません。いずれにしろ、もう少し SDK がどういう役割をしているのかも把握しないと、思わぬ所でハマってしまいそうです。

ようやく私の周りで IDE からの直接発行ではなく、MSBuild でビルドするという流れになりましたが、結構 IDE はよしなにやってくれている事が多いのだなーと思いますね。ビルドを自動化するためには、ちょっとずつ IDE からの依存を切っていかないといけないので、まだまだ先は長そうです。

NUnit(とか) に簡単なアサーションを提供してくれる Chaining Assertion

先日の Should の記事の

ブックマークコメントで id:neuecc さんにコメントいただき、「Chaining Assertion」を紹介いただきました。neuecc さんはライブラリの作者さんですね。ありがとうございます。

Should はどうだ?

個人的には、Should の書き方にはそれほど違和感ありません。NSpec のように should_be のようだと ruby っぽいし、見た目にも読みやすいから好きなのですが、社内の人の中には C# っぽくないから嫌だとの意見もあるためこの辺も人によりそうです。

ただ、ShouldFluent の書き方は実際書いてみてかなり面倒くさいなーというのは感じました。特に私がドットをよく押し間違えるので、ちょっとしたストレスに。。(完全私のせいですが。)
ただ、それを差し引いても、ちょっとメリットが見えなかったので結局 Should の方で書いていました。

以下の記事でも言及されていますね。
テストを簡単にするほんの少しの拡張メソッド - neue cc

Chaining Assertion

使い方

例によって、CodePlex の方のサンプルで十分なので先日の Should, ShouldFluent と比較したものだけ以下に記載します。
NuGet で取得した時に dll ではなくソースが追加されるだけってのはいいですね。すぐ中を見ることができる。

[TestFixture]
public class dSample {

    [TestCase]
    public void TestShouldAny() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.ShouldNotBeEmpty();
        exist.ShouldNotBeNull();
        exist.ShouldBeSameAs(exist);
        exist.ShouldBeType<string>();
        exist.ShouldContain("su");
        exist.ShouldEqual("result");

        empty.ShouldBeEmpty();
        stringEmpty.ShouldBeEmpty();
        nullValue.ShouldBeNull();
    }

    [TestCase]
    public void TestShouldFluent() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.Should().Not.Be.Empty();
        exist.Should().Not.Be.Null();
        exist.Should().Equals(exist);
        exist.ShouldBeType<string>();
        exist.Should().Contain("su");
        exist.Should().Equal("result");

        empty.Should().Be.Empty();
        stringEmpty.ShouldBeEmpty();
        stringEmpty.Should().Be.Empty();
        nullValue.Should().Be.Null();
    }

    [TestCase]
    public void TestChainingAssertion() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.IsNotNull();
        exist.IsSameReferenceAs(exist);
        exist.IsInstanceOf<string>();
        exist.Is(s => s.Contains("su"));
        exist.Is("result");

        empty.Is(string.Empty);
        stringEmpty.Is(string.Empty);
        nullValue.IsNull();
    }
}

実際ソースを見てみてもわかるのですが、非常にシンプルでキレイです。確かに rspec を見て、最初に思ったのは、「すげー簡単にテストかけるんだなー」って部分が一番大きくて、should って記法で書けることに感動したわけじゃなかったよなと改めて思い出しました。

次は

DynamicAccessor 使ってみたいですね。Private なものをテストしなきゃいけなくなる事自体が決して良い状況じゃないですが、レガシーコードをテストするには欠かせない部分の気がするのですごく活用したいです。

という訳で、「Should はもういいかな」。

NUnit に Spec っぽい書き方を提供する Should

社内では

NUnit が主流なのですが、やっぱり rspec みたいな should〜 って書き方は読みやすいなーと思うのです。Assert はそれはそれで見慣れているのですが。
NSpec や MSpec のような BDD フレームワークを使えばというのもあるのですが、QAという立場上開発が主で使うツールをとやかく言うのもアレなので、NUnit でも Spec っぽく書けるラッパーを書いたりしてたのですが、やはり先人はいました。

Should Assertion Library

このライブラリは NUnit を含む複数のテストライブラリに should のシンタックスを追加するものです。

インストール

ダウンロードして参照に加えるか、NuGetをインストールしていれば以下。
ShouldFluent は Should の fluent API 版です。

Install-Package Should
Install-Package ShouldFluent
使い方

CoddPlex のサイトの方に詳細なサンプルがあるので、そちらを見てもらう方が早いですが、簡単に記述すると以下のようになります。

[TestFixture]
public class ShouldSample {
    [TestCase]
    public void TestAssertIsTrue() {
        Assert.IsTrue(true); // NUnit の Assert
    }

    [TestCase]
    public void TestShouldBeTrue() {
        true.ShouldBeTrue(); // 同じものを Should で記述。
    }

    [TestCase]
    public void TestShouldBeTrueFail() {
        false.ShouldBeTrue(); // もちろん失敗します。
    }

    // Should で基本的なアサーションを記載
    [TestCase]
    public void TestShouldAny() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.ShouldNotBeEmpty();
        exist.ShouldNotBeNull();
        exist.ShouldBeSameAs(exist);
        exist.ShouldBeType<string>();
        exist.ShouldContain("su");
        exist.ShouldEqual("result");

        empty.ShouldBeEmpty();
        stringEmpty.ShouldBeEmpty();
        nullValue.ShouldBeNull();
    }

    // ShouldFluent で上記の Should の例を書きなおし
    [TestCase]
    public void TestShouldFluent() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.Should().Not.Be.Empty();
        exist.Should().Not.Be.Null();
        exist.Should().Equals(exist);
        // exist.ShouldBeType<string>(); この例だけ ShouldFluent で書き直せない?
        exist.Should().Contain("su");
        exist.Should().Equal("result");

        empty.Should().Be.Empty();
        stringEmpty.ShouldBeEmpty();
        stringEmpty.Should().Be.Empty();
        nullValue.Should().Be.Null();
    }
}

とまあ、NUnit でテストを書かれている方からすれば、シンタックスが違うだけで、何も変わらないと思います。本当にアサーションの部分だけ Spec ぽく書いているだけなので BDD っぽくも何もないですね。

何か嬉しい?

個人的に最近 SpecFlow にハマっているのですが、SpecFlow は NSpec や MSpec を現状サポートしておらず、NUnit や MSTest で書くしかない状態です。(とはいえ、NSpec とかは NUnit のラッパーでしかないのでなんとかなるのかもしれませんが。)
特に SpecFlow はDSL的にメソッドを記述していくので、Assert より Should でアサーションした方がなんか見やすい気がしているのです。まあ、この辺は好みの問題でしかないと思いますが。

もっと .NET でも Spec が流行るといいですね!