athome-developer’s blog

不動産情報サービスのアットホームの開発者が発信するブログ

JavaScriptとC#の日付型の受け渡しで嵌った件

情報システム部の高野です。アーキテクチャ構築をメーンに担当しています。

今回は、JavaScriptのDate型をAjaxC#のDateTime型にバインドさせた時に嵌った話です。
(そもそも文字列型に変換してから送ればいい、という話は棚の上に置いておきます)

とりあえず環境
・クライアント
→AngularJS(AjaxもAngularを使って実行)
・サーバ
ASP.NET Core MVC 1.0


下の画像のようなコントロールに入力したデータをサーバに送信します。
(Angular UIを利用しています)
f:id:taktak1974:20160714134256p:plain

サーバ側で見るとこうなります。
f:id:taktak1974:20160714134238p:plain
UTCになってる!
しょうがないので、C#側でローカルタイムに変換します。

これで問題解決と思ったのですが、別の問題が発生します。
この登録したデータを編集するためにクライアント側で開きます。
IEやedgeだと問題はありません。
f:id:taktak1974:20160714134832p:plain
でもchromeだと、
f:id:taktak1974:20160714135112p:plain
9時間後になってしまいます!

これはC#側でちょろっと変換しておけばいいや、という話ではなくなりました。
なにか根本的に問題がある!

そこでいろいろ調べました。
Angular UIの設定?
JavaScriptのDate型になにかすればいいの?
AngularJSのAjax処理?

で、行きついたのはJson.NETの設定でした。
たどり着くまでかなり遠回りをしましたが、分かってしまえば簡単で、
StartupのConfigureServicesメソッドに設定を追加するだけでした。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddJsonOptions(options => {
            options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            options.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
        });
   …
}

AddJsonOptionsの2つ目の設定が必要でした。
(ちなみに、1つ目の設定は、JSONのプロパティ名の頭を小文字にする設定です。)

この設定をすることによりわざわざローカルタイムに変換する処理もいらなくなりますし
chromeでも正しい時間が表示されます。


一応、解決はしましたが根本的な原因が分かっていないので
今後、時間ができたら調べてみたいと思います。

あ、国内でしか使わないシステムなのでこのような対応にしています。あしからず。