アーカイブ

Posts Tagged ‘ASP.NET’

.net coreにおける設定値の解決

2018年11月16日 1件のコメント

.net coreにおける設定値の解決は、これまでの.NETに比べだいぶ柔軟になってきていて、設定の取得先が設定ファイル以外からも柔軟に取り出せるようになってきました。

asp.net core の雛形を何回か作り直しているので個人的にちょっとまとめています。

概要

これまで、NETの開発では、データベースの接続文字列や、認証周りの設定など、アプリケーションの動作環境ごとに変化しうる値は設定ファイル(web.config or app.config)に保存し、プログラム起動時に設定情報を取得するという方針がとられることが多かったわけですが、.net coreではjsonファイルの他にも環境変数やコマンドラインの情報を合成して設定値を取り扱うことができます。

.net core 設定情報の指定

ASP.NET Coreでは、プログラム起動時のパイプライン設定にProviderを追加していくことで、設定ファイル以外からの設定値を柔軟に利用できるようになっています。
下のASP.NET Coreのエントリーポイントの例では、ConfigureAppConfigurationメソッド内でAddJsonFileメソッドや、AddEnvironmentVariablesメソッド、AddCommandLineメソッドを指定することで設定ファイル以外にも、環境変数やコマンドラインから設定値を取り出すことができるようにしています。

        public static IWebHost CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    var env = hostingContext.HostingEnvironment.EnvironmentName;
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddJsonFile("connectionStrings.json");
                    config.AddJsonFile($"connectionStrings.{env}.json", optional: true);

                    config.AddEnvironmentVariables();
                    config.AddCommandLine(args);
                })
                .UseSerilog()
                .UseStartup()
                .Build();
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Run();
        }

この他、.NET Coreで標準に用意されているProviderの一覧は下記のURLで確認することができます。
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1

設定値の利用

例えば、Jsonファイルに下記のように値が設定されている場合、プログラムからはいくつかの方法で設定値を取得することができます。

{
  "Header": {
    "Title": "ASP.NET Coreの設定",
    "Author": {
      "Name": "karuakun",
      "Mail": "karuakun@gmail.com"
    }
  },
  "SharedFor": [
    { "ClientId": 1, "Role": "Author" },
    { "ClientId": 2, "Role": "Reviewer" }
  ]
}

設定値をConfiguration変数から直に取得する

GetValueメソッドで設定値を参照できます。複雑なオブジェクトの場合、: で階層を区切って取得することができます。

            var title = configuration.GetValue("Header:Title");
            var role = configuration.GetValue("SharedFor:0:Role");

配列は添字でアクセスすることになるので、他のProviderで上書きを想定している場合は、設定ファイルの構成を配列よりもオブジェクトとして定義したほうが後々楽になります。

"Clients": [
    { "Name": "karuakun1", "OS": "Windows" },
    { "Name": "karuakun2"}
]

の karuakun1 の値を上書きたい場合 "Client:0:OS" でアクセスするより、設定は冗長になるけれど

"Clients": { 
    "karuakun1": { "Name": "sugiyama", "OS": "Windows" },
    "karuakun2": { "Name": "kezuka" }
}

として、"Client:karuakun1:OS" でアクセスできるようにしたほうが方が安定します。

設定値を特定のEntityにマップして取得する

JSONオブジェクトを特定のクラスにマップすると、型安全な方法で設定値にアクセスすることができます。

configuration.GetSection("Clients:karuakun1").Get()

設定値を取得する場合、GetSectionの他に、GetChildren、Existsなどを利用することもできます。
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1#getsection-getchildren-and-exists

IOptionインターフェイス経由で取得する

ASP.NET Coreで設定値を利用する場合、この方法が一般的になると思います。
Controllerや各サービスクラスで設定を利用する場合、これまでのASP.NETでは、ConfigurationSectionクラスから直に読んだり、Startup時に作成したStaticクラスから値を取得することが多かったけれど、ASP.NET CoreではDIが根本にあるので、設定値の取得でもConfigureService時にConfigureメソッドで登録した値を、各クラスのコンストラクタで受け取る形で利用するように変更されています。

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure(Configuration.GetSection("Clients:karuakun1"));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
    public class HomeController : Controller
    {
        public HomeController(ILoggerFactory _logFactory, IOptions userOption)
        {
            var logger = _logFactory.CreateLogger();
            var user = userOption.Value;
            logger.LogInformation($"UserName={user.Name}");
        }
    }

C#のコード以外にもRazorページで参照したり、変更をキャッシュしたりする場合の詳細は下記のドキュメントを参照。
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/configuration/options?view=aspnetcore-2.1

値の設定

.net core ではJson以外にも、環境変数やコマンドラインから設定値を取得できるんだけれど、どの値が採用されるかはIConfigurationBuilderに追加した順に上書きされるので、下記の順で登録した場合、connectionString.json, connectionString.debug.json, 環境変数、コマンドライン引数が順に読み込まれて上書きされる。

                    config.AddJsonFile("connectionStrings.json");
                    config.AddJsonFile($"connectionStrings.{env}.json", optional: true);
                    config.AddEnvironmentVariables();
                    config.AddCommandLine(args);

コマンドラインからの設定値の指定

AddCommandLineメソッドでコマンドラインの設定値を有効にすると、アプリケーション起動時に指定したパラメーターを設定値として利用される

dotnet run --Clients:karuakun1:Name sugiyama --Clients:karuakun1:OS Hage

/ --といったコマンドラインスイッチに関しては下記URLを参照。
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1#arguments

環境変数の指定

コマンドライン同様、AddEnvironmentVariablesメソッドを有効にすると、環境変数で設定したパラメーターを設定値として利用することができる。

set Clients:karuakun1:OS=HageHage
dotnet run

環境変数を利用すると、.net アプリケーションをdockerで起動する際に相性が良く、docker-composeファイルのEnvironmentセクションに列挙することで、コンテナの外部から設定値を書き換えることができる。

参照

ASP.NET Core のオプション パターン
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/configuration/options?view=aspnetcore-2.1

ASP.NET Core のアプリケーション構成を上書きするいろいろ – 特に環境変数とコレクション
https://devadjust.exblog.jp/27132532/

広告
カテゴリー:ASP.NET, Docker タグ:

EntityFramework のマイグレーションで複数のContextが含まれる場合は -c (-context)オプションを利用する。

Dataプロジェクトに
AppDbContext と AuthDbContext という複数のコンテキストがあった場合、普通にdotnet ef migrations add とかするとこんな感じで怒られるので

More than one DbContext was found. Specify which one to use. Use the ‘-Context’ parameter for PowerShell commands and the ‘–context’ parameter for dotnet commands.

-c もしくは -context オプションを利用する。
https://docs.microsoft.com/ja-jp/ef/core/managing-schemas/migrations/providers

さらに複数のコンテキストのマイグレーションが同じフォルダーで混ざると気持ち悪いので、-o -output オプションを付けてマイグレーションフォルダーを分けると嬉しい

dotnet ef migrations add InitAppDbContext -c AppDbContext -o Migrations/App
dotnet ef migrations add InitAuthDbContext -c AuthDbContext -o Migrations/Auth

もちろん dotnet ef database update 時にも -c をつけるのをお忘れなく

dotnet ef database update -c AppDbContext
dotnet ef database update -c AuthDbContext
カテゴリー:ASP.NET, MySql タグ: ,

Visual Studio 2017 15.8でdocker-composeを利用する場合は、コンテナオーケストレーターレーターサポートからdocker-compose.ymlを追加する

Visual Studio 2017 バージョン 15.8 で Docker サポートを有効にした ASP.NET Core のアプリケーションを作ったら、docker-compose.yml が自動的に追加されなかったのでメモ

Visual Studio Tools for Docker と ASP.NET Core」の「アプリにコンテナー オーケストレーター サポートを追加する」を参照すると、下記のような記載が追加されていた。

Visual Studio 2017 バージョン 15.8 以降では、指示された場合にのみ、オーケストレーション ソリューションが追加されます。 ソリューション エクスプローラーでプロジェクトを右クリックして、[追加] > [Container Orchestrator Support](コンテナー オーケストレーター サポート) の順に選択します。 Docker Compose と Service Fabric という 2 つの異なる選択肢が提供されています。

MSDNにある通り、プロジェクトのプロパティー > 追加 > コンテナオーケストレーターサポートを選択し、
DockerComposeの追加1

Docker Compose を選択すると、
DockerComposeの追加2

ベースイメージを Windows にするか Linux にするかを尋ねられるのでOSを選択する。
DockerComposeの追加3

ソリューションに docker-compose が追加され、スタートアッププロジェクトに設定される。
DockerComposeの追加6

こんな感じの docker-compose.yml が追加される。

 version: '3.4'

services:
  webapplication1:
    image: ${DOCKER_REGISTRY}webapplication1
    build:
      context: .
      dockerfile: WebApplication1/Dockerfile

複数のプロジェクトに対してコンテナオーケストレーターサポートを追加すると、docker-compose.yml に設定が追加されるので、必要に応じてdepends_onを設定すればよい。

version: '3.4'

services:
  webapplication1:
    image: ${DOCKER_REGISTRY}webapplication1
    build:
      context: .
      dockerfile: WebApplication1/Dockerfile

  webapplication2:
    image: ${DOCKER_REGISTRY}webapplication2
    build:
      context: .
      dockerfile: WebApplication2/Dockerfile
カテゴリー:ASP.NET, Docker タグ: ,

ついにこの時が、、、No More WebForms, No More Visual Basic

Top 10 Changes in ASP.NET 5 and MVC 6

いや、わかってたんですよ。わかってはいましたが、、、

No More Web Forms

You can continue to build Web Forms apps in Visual Studio 2015 by targeting the .NET 4.6 framework. However, Web Forms apps cannot take advantage of any of the cool new features of ASP.NET 5 described in this list. If you don’t want to be left behind as history marches forward then it is finally time for you to rewrite your Web Forms app into ASP.NET MVC.

超意訳

引き続きVisual Studio 2015でも.NET 4.6を選択すればWebFormsのビルドを行うことができます。しかし、ASP.NET WebFormsではASP.NET 5の新機能を利用することはできません。これはASP.NETの進化に取り残されたくない場合ASP.NET WebFormsアプリをASP.NET MVCアプリに書き換えるための猶予期間なのです。

カテゴリー:ASP.NET, Visual Basic タグ:

kproj と KRuntimeってなに??

ASP.NETのソースコードがGitHubで公開されたというので、とりあえずさらっと眺めようかとソースを取り寄せてVisual Studioでソリューションファイルを読み込んでみると、各プロジェクトは 「kproj」 という拡張子を持つプロジェクトファイルで構成されているようでVisual Studioで読み込むことができませんでした。

kprojってなんだろう。

ASP.NET vNext HomeをみるとGetting StartedにK Version Managerへのリンクが貼られています。どうもASP.NET vNextの開発はK Runtimeという開発時と実行時のランタイムの溝を埋める環境で開発されているようです。kprojはこのK Runtimeで動作するプロジェクトを作成するためのプロジェクトファイルみたいです。

でもって、今のところkprojを理解するためのVisual Studioの拡張機能はなさそう。そのうち出てくるんだろうけれど、ソースを見たいならテキストエディターやらで確認するしか無いのかな?

カテゴリー:ASP.NET タグ:

何故かクッキーレスセッションになってしまった

IE11が電撃的に自動配布されたわけですが、皆様いかがお過ごしでしょうか?

IE11が自動配布されたクライアントで、何故かASP.NETのセッション情報がクッキーレスセッションで運用される状況になったので対応をメモ。現在現象発生まち。。。

IE11の自動配布について

今回は開始されまでが早かったですね。去年このブログのエントリーは確認していたんですが、自分の環境のIE11では問題なく動いていたので、今週の配布で問題が出るとは思っていませんでした。

2014 年 1 月第 2 週目から順次、Windows 7 向けInternet Explorer 11 の自動アップグレードを開始します

ブラウザー定義ファイルの更新

ASP.NETでブラウザーの更新における問題というと、ブラウザー定義ファイルの更新漏れが考えられるのでまずはこちら。_doPostbackが定義されていないとか言ったJavascriptのエラーが出るならまずは確認してみましょう。

セッション情報と認証情報は無条件にクッキーへ

いや、いまさらクッキー使えない端末とか無いから気にしないでクッキーへ書こうよということなら、web.configのforms要素とsessionState要素の設定をUserCookiesで指定してあげます。

カテゴリー:ASP.NET, プログラミング, Windows タグ: ,

IE10 関連リソース

先日、Windows 7 対応のInternet Explorer 10がリリースされました。

普段使っていく文には、高速化、リッチコンテンツへの対応というメリットがありますが、提供する側としては検証ブラウザー対象のブラウザーが増えるのでちょっと大変ですね。とりあえず検証用のリンクをメモしておきます。

まずは代表的な2つのURL

上記の中でリンクされている中で、特に気にしておいたほうがよさそうなもの

で、更にASP.NETがInternet Explorer 10の検出に失敗するに関しては、サーバー側の設定ファイルの変更が必要なので、ココも合わせてみたい。

Bug and Fix: ASP.NET fails to detect IE10 causing _doPostBack is undefined JavaScript error or maintain FF5 scrollbar position

カテゴリー:ASP.NET, Windows タグ: ,