Azureのテンプレートファイルをモデルクラスから作成したい

[この記事](https://qiita.com/piyo8810/items/f15d69d90a360ce056ca) に書いてあることを実現するために、Azureのテンプレートファイルを生成する必要がある。

テンプレートファイルはJSON形式。例えば、WebAppsは以下のURLにある通り。(この記事を書いた時点でのURLなので、将来変わるかも)

https://docs.microsoft.com/ja-jp/azure/templates/microsoft.web/allversions

そこで、要求されているパラメータをクラスのメンバーにして、Newtonsoft.Jsonを使ってモデルクラスをJSONにシリアライズすればいいかな、と考えた。

#0. (2020/05/24更新)結論を言うとうまく使えなかった
何日かいじってみたけど、結局SDKのモデルを使うのはやめて、独自でモデルクラスを定義することにした。
なんつっても、以下のような「properties.」が痛い。これいらない。

```C#
properties.isXenon": null
```
 
必要なのは「isXenon」だけなので、[Jsonproperty(name=)]みたいなやつで何とかしたい。しかし、SDKを継承しているだけなので手が出せない。
必須パラメーターだけに絞ればそんなに大した量でもないし、本来であればテンプレートの構造に従ったモデルクラスを定義すべきであると思ったので、この方式はやめた｡｡｡｡

以下は、一応備忘録ということで残しておくけど、もう使うことはない･･･さらば･･･


#1. SDKからモデルを拝借

でも、テンプレートファイルの形式に沿った自前でクラス作ると、Azure側の変更とかに追従しなきゃいけなくなったりして面倒。

なにか簡単な方法ないかな････ということで、.NET SDKのモデルクラスを借りることにした。例えば以下。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.management.websites.models.site?view=azure-dotnet

これを見ると、テンプレートのMicrosoft.Web sites templateにかなり近い構造を持っていることがわかる。

なので、このクラスを継承した独自のクラスを作れば････！

```C#
using Microsoft.Azure.Management.WebSites.Models;
//...(中略)...
    class SiteModel : Microsoft.Azure.Management.WebSites.Models.Site
    {
        public string type = "Microsoft.Web/sites";
        public string apiVersion = "2019-08-01";

        public SiteModel()
        {
        }
```

#2. 発生した問題と解決法
継承したモデルを使ってWebAppsの名前を設定するプロパティに値を入れようとしたら、getしか認められていない････

つまり、WebAppsに好きな名前を設定できない。

なので、外部からWebAppsの名前を設定したかったら、コンストラクタを生成する段階で名前を入れておく必要がある。

コンストラクタの引数はバカ多いものの、幸い必須なのはlocationだけのようなので、locationとnameだけを指定できるようコンストラクタを追加。

```C#
public SiteModel(string location, string name) : base(location: location, name: name)
{
}
```

#3. JSON形式にシリアライズ
準備はできた。早速シリアライズや！

```C#
using Newtonsoft.Json;
using System;

namespace jsontest2
{
    class Program
    {
        static void Main(string[] args)
        {
            var site = new SiteModel(location: "Japan East", name: "testSite");
            string json = JsonConvert.SerializeObject(site, Formatting.Indented);

            Console.WriteLine(json);
       }
    }
}
```

出力は以下。

```
{
  "type": "Microsoft.Web/sites",
  "apiVersion": "2019-08-01",
  "properties.state": null,
  "properties.hostNames": null,
  "properties.repositorySiteName": null,
  "properties.usageState": null,
  "properties.enabled": null,
  "properties.enabledHostNames": null,
  "properties.availabilityState": null,
  "properties.hostNameSslStates": null,
  "properties.serverFarmId": null,
  "properties.reserved": null,
  "properties.isXenon": null,
  "properties.hyperV": null,
  "properties.lastModifiedTimeUtc": null,
  "properties.siteConfig": null,
  "properties.trafficManagerHostNames": null,
  "properties.scmSiteAlsoStopped": null,
  "properties.targetSwapSlot": null,
  "properties.hostingEnvironmentProfile": null,
  "properties.clientAffinityEnabled": null,
  "properties.clientCertEnabled": null,
  "properties.clientCertExclusionPaths": null,
  "properties.hostNamesDisabled": null,
  "properties.outboundIpAddresses": null,
  "properties.possibleOutboundIpAddresses": null,
  "properties.containerSize": null,
  "properties.dailyMemoryTimeQuota": null,
  "properties.suspendedTill": null,
  "properties.maxNumberOfWorkers": null,
  "properties.cloningInfo": null,
  "properties.resourceGroup": null,
  "properties.isDefaultContainer": null,
  "properties.defaultHostName": null,
  "properties.slotSwapStatus": null,
  "properties.httpsOnly": null,
  "properties.redundancyMode": null,
  "properties.inProgressOperationId": null,
  "identity": null,
  "id": null,
  "name": "testSite",
  "kind": null,
  "location": "Japan East",
  "tags": null
}
```

いやプロパティがバカ多いな。いらないやつは出さなくていいぞい。
実際、自前のWebAppsをテンプレート化してみたら「hostNameSslState」とか無かったし。
パラメータ自体はフルセットだから当然クソほどあるんだろうけど、実際すべてのパラメータをフルに使うなんてそうそうない気がする。

というわけで、シリアライズ時に引数を渡します。

```C#
string jsonExcludeNull = JsonConvert.SerializeObject(site, new JsonSerializerSettings {
     NullValueHandling = NullValueHandling.Ignore, 
     Formatting = Formatting.Indented });
```

こうすると、出力が以下のように。

```
{
  "type": "Microsoft.Web/sites",
  "apiVersion": "2019-08-01",
  "name": "testSite",
  "location": "Japan East"
}
```

いいんじゃないのこれー！？！？！？テンプレートファイルみたいにできるかも！！！
あとは階層構造みたいなんがうまくいけば、もうコレほぼ完成だろコレおい。
････とテンションが上がったところで今日は終わります。


あと、全然関係ないけどAZ-103受けたら合格した。
PaaSばっか触っててあんまIaaSとか詳しくないけど、1か月くらいそれなりに勉強したら受かりました。
うぇい。