C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: FullCarendarのイベントソース取得について


(過去ログ 178 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■102101 / inTopicNo.1)  FullCarendarのイベントソース取得について
  
□投稿者/ あああ (4回)-(2023/07/02(Sun) 23:14:33)

分類:[ASP.NET (C#)] 

【開発環境】
.NetFramework4.7.2
visualsutudio 2019 asp.net MVC
fullcarendar v6.18

【困っていること】
DBよりイベントを取得しカレンダー上に表示させたいがFullcarendarのjavascript上で下記エラーが発生する。

index.global.min.js:6  Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'display' in [
    at _n (index.global.min.js:6:50229)
    at Zn (index.global.min.js:6:55081)
    at Yn (index.global.min.js:6:53660)
    at On (index.global.min.js:6:51106)
    at index.global.min.js:6:107490
    at Es (index.global.min.js:6:107564)
    at ha._handleAction (index.global.min.js:6:163499)
    at da.runTask (index.global.min.js:6:159053)
    at da.drain (index.global.min.js:6:158979)
    at Ps.drained (index.global.min.js:6:112906)


【スクリプト】
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js'></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

document.addEventListener('DOMContentLoaded', function () {
        var calendarEl = document.getElementById('calendar');
        var calendar = new FullCalendar.Calendar(calendarEl, {
            locale: 'ja',
            buttonText: {
                today: '今日',
                month: '月',
                week: '週',
                day: '日',
                list: 'リスト'
            },
            views: {
                week: {
                    allDayText: '終日'
                },
                day: {
                    allDayText: '終日'
                }
            },
            headerToolbar: {
                left: 'prev,next today',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
            },
            businessHours: {
                daysOfWeek: [1, 2, 3, 4, 5],
                startTime: '08:00',
                endTime: '17:00',
            },
            initialView: 'dayGridMonth',
            eventSources: [
                {
                    url: '/Home/GetEvents',  // イベントデータを取得するURL
                    type: 'GET',         // データを取得するHTTPメソッド
                    color: 'blue'        // イベントの色
                }
            ]
        });
        calendar.render();
    });

【コントローラ】
[HttpGet]
        public ActionResult GetEvents()
        {
            EventRepository er = new EventRepository();

            // データベースからイベントデータを取得する処理
            var eventData = er.GetEventsFromDatabase();

            // オプション設定
            var options = new JsonSerializerOptions
            {
                // 日本語を変換するためのエンコード設定
                Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),

                // プロパティ名をキャメルケースに変換
                //PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

                // インデントを付ける
                WriteIndented = true
            };

            // シリアライズ
            var jsonString = JsonSerializer.Serialize(eventData, options);

            return Json(jsonString,JsonRequestBehavior.AllowGet);
        }
    }

【model】
 public class EventModel
    {
        public string Id { get; set; }
        public string Title { get; set; }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
    }

    public class EventRepository
    {
        //Mysql接続文字列

        public List<EventModel> GetEventsFromDatabase()
        {
            List<EventModel> events = new List<EventModel>();

            // データベースからデータを取得する処理を実装
            // EventModelオブジェクトにマッピングして返す
            //Mysql操作用
            MySqlConnection sqlConn = new MySqlConnection(); //DB接続用

            try
            {
                MySqlConnectionStringBuilder sqlBuilder = new MySqlConnectionStringBuilder();
                sqlBuilder.Server = server;
                sqlBuilder.UserID = userID;
                sqlBuilder.Password = pass;
                sqlBuilder.Database = database;

                //接続文字列設定
                sqlConn.ConnectionString = sqlBuilder.ConnectionString;

                //DB接続
                sqlConn.Open();

                //DB操作
                MySqlDataAdapter sqlDtA = new MySqlDataAdapter();

                MySqlCommand sqlCmd = sqlConn.CreateCommand();

                //SQL文作成
                sqlCmd.CommandText = @"SELECT * ";
                sqlCmd.CommandText += @"FROM T_yoyaku ";


                //SQL文実行
                MySqlDataReader sqlReader = sqlCmd.ExecuteReader();

                //testTable内にデータが入っているか判定
                if (sqlReader.HasRows)
                {
                    //レコード分ループする
                    while (sqlReader.Read())
                    {
                        EventModel eventModel = new EventModel
                         {
                             Id = sqlReader["id"].ToString(),
                             Title = sqlReader["title"].ToString(),
                             Start = Convert.ToDateTime(sqlReader["start"]),
                             End = Convert.ToDateTime(sqlReader["end"])
                         };
                        events.Add(eventModel);
                    }
                    
                }

                sqlReader.Close();

                sqlCmd.Dispose();

                return events;

            }
            catch
            {
                return events;
            }
            finally
            {
                // 接続解除
                sqlConn.Close();
                sqlConn.Dispose();
            }

        }
    }

【補足】
コントローラで返しているJSONデータの中身は
[
  {
    "Id": "1",
    "Title": "イベント",
    "Start": "2023-07-02T00:00:00",
    "End": "2023-07-03T00:00:00"
  },
  {
    "Id": "2",
    "Title": "イベント",
    "Start": "2023-07-04T00:00:00",
    "End": "2023-07-05T00:00:00"
  }
]
となっています。


色々調べても修正方法が分からずどなたか助けていただけませんか。



引用返信 編集キー/
■102102 / inTopicNo.2)  Re[1]: FullCarendarのイベントソース取得について
□投稿者/ WebSurfer (2722回)-(2023/07/02(Sun) 23:19:15)
No102101 (あああ さん) に返信

先にあなたが立てたスレッド ↓ を放置しておかないでクローズしてください。

http://bbs.wankuma.com/index.cgi?mode=al2&namber=102078
引用返信 編集キー/
■102104 / inTopicNo.3)  Re[2]: FullCarendarのイベントソース取得について
□投稿者/ あああ (6回)-(2023/07/02(Sun) 23:23:26)
No102102 (WebSurfer さん) に返信
> ■No102101 (あああ さん) に返信
>
> 先にあなたが立てたスレッド ↓ を放置しておかないでクローズしてください。
>
> http://bbs.wankuma.com/index.cgi?mode=al2&namber=102078

大変申し訳ありませんでした。解決済みにさせていただきました。
引用返信 編集キー/
■102107 / inTopicNo.4)  Re[1]: FullCarendarのイベントソース取得について
□投稿者/ WebSurfer (2723回)-(2023/07/03(Mon) 09:57:52)
No102101 (あああ さん) に返信

jQuery プラグインの Fullcarendar、ASP.NET MVC、MySQL、Connector/NET 関わって
いるモノが盛りだくさんなのですが、それを全部投げてきてデバッグしてくれと言わ
れているような気がします。

それは回答者・閲覧者に期待しすぎだと思います。

質問者さんの方で切り分けをして、どのあたりに問題がありそうかを調べるというこ
とはできませんか?

それができる環境を今現在すでに持っていて、今すぐ切り分けができるのは質問者さ
んだけです。なので、まずは質問者さんの方である程度切り分けしてから、問題の原
因と思われる部分だけを提示して質問するようにしましょう。

とりあえずぱっと見気が付いた点のみ書いておきます。

> var jsonString = JsonSerializer.Serialize(eventData, options);
> return Json(jsonString,JsonRequestBehavior.AllowGet);

1 行目で System.Text.Json 名前空間の JsonSerializer クラスを使って JSON 文字列
にシリアライズして、それを 2 行目で MVC5 の Json メソッド (Newtonsoft.JSON を使
っているはず) でもう一回 JSON 文字列にシリアライズしています。何か意味があるの
ですか?

Fullcarendar は自分は触ったこともないの分かりませんが、渡すデータの形式 (特に
日時) は仕様に合っているのでしょうか?

引用返信 編集キー/
■102108 / inTopicNo.5)  Re[1]: FullCarendarのイベントソース取得について
□投稿者/ 魔界の仮面弁士 (3661回)-(2023/07/03(Mon) 10:50:53)
No102101 (あああ さん) に返信
> index.global.min.js:6  Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'display' in [
こっちのエラーの理由はわかりませんが:


> [
>   {
>     "Id": "1",
>     "Title": "イベント",
>     "Start": "2023-07-02T00:00:00",
>     "End": "2023-07-03T00:00:00"
>   },
>   {
>     "Id": "2",
>     "Title": "イベント",
>     "Start": "2023-07-04T00:00:00",
>     "End": "2023-07-05T00:00:00"
>   }
> ]

JSON の大文字小文字が間違っていませんか?
手元のデバッガで試してみると、小文字にしないとイベントを認識しませんでしたが。
https://fullcalendar.io/docs/event-source-object

[
  {
    "id": "1",
    "title": "イベント",
    "start": "2023-07-02T00:00:00",
    "end": "2023-07-03T00:00:00"
  },
  {
    "id": "2",
    "title": "イベント",
    "start": "2023-07-04T00:00:00",
    "end": "2023-07-05T00:00:00"
  }
]

引用返信 編集キー/
■102109 / inTopicNo.6)  Re[2]: FullCarendarのイベントソース取得について
□投稿者/ WebSurfer (2724回)-(2023/07/03(Mon) 11:31:27)
No102108 (魔界の仮面弁士 さん) に返信

> JSON の大文字小文字が間違っていませんか?
> 手元のデバッガで試してみると、小文字にしないとイベントを認識しませんでしたが。

質問者さんのコードで、

// プロパティ名をキャメルケースに変換
//PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

と、コメントアウトしてしまった結果そうなります。

訳が分からずいじりまくったのだと思いますが。
引用返信 編集キー/
■102110 / inTopicNo.7)  Re[3]: FullCarendarのイベントソース取得について
□投稿者/ 魔界の仮面弁士 (3662回)-(2023/07/03(Mon) 12:14:57)
2023/07/03(Mon) 12:48:28 編集(投稿者)

No102109 (WebSurfer さん) に返信
> // プロパティ名をキャメルケースに変換
> //PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
> と、コメントアウトしてしまった結果そうなります。

PropertyNamingPolicy の問題についてはそれでよいとして、
本題の in 演算子のエラーについては、質問事項に記載されていない箇所に
問題がありそうですね…。



No102101 (あああ さん) に返信
> fullcarendar v6.18

fullca"r"endar ではなく
FullCa"l"endar ですね。


> index.global.min.js:6 Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'display' in [

何か別の場所でスクリプトエラーが発生していませんか?

内部処理にて
 at _n (index.global.min.js:6:50229)
  :
 at Ps.drained (index.global.min.js:6:112906)
の部分で何かが起きているのでしょうけれど、それを第三者が判断するのは難しそうです。


in 演算子は本来、「配列」や「オブジェクト」に対して利用されるものであるのに、
誤ってそれが文字列に対して呼び出されてしまっているようです。
多分、何か別のエラーでスタックトレースが返されている状態。
(実際には Promise オブジェクトのエラー処理が正しく行われていないのだと予想)

--- これは OK ---
'display' in []; // 配列
'display' in {}; // オブジェクト

--- これは NG ---
'display' in "[]"; // 文字列



たとえば
 'display' in '[\n\tat _n (index.global.min.js:6:50229)]\n\tat Zn (index.global.min.js:6:55081)';
というコードが実行された場合、コンソールに
 Uncaught TypeError: Cannot use 'in' operator to search for 'display' in [
  at _n (index.global.min.js:6:50229)]
  at Zn (index.global.min.js:6:55081)
というエラーが出力されます。
引用返信 編集キー/
■102111 / inTopicNo.8)  Re[1]: FullCarendarのイベントソース取得について
□投稿者/ WebSurfer (2725回)-(2023/07/03(Mon) 13:26:37)
No102101 (あああ さん) に返信

ちょっと試してみました。

No102107 で、

>>var jsonString = JsonSerializer.Serialize(eventData, options);
>>return Json(jsonString,JsonRequestBehavior.AllowGet);
> 
> 1 行目で System.Text.Json 名前空間の JsonSerializer クラスを使って JSON 文字列
> にシリアライズして、それを 2 行目で MVC5 の Json メソッド (Newtonsoft.JSON を使
> っているはず) でもう一回 JSON 文字列にシリアライズしています。何か意味があるの
> ですか?
> 
> Fullcarendar は自分は触ったこともないの分かりませんが、渡すデータの形式 (特に
> 日時) は仕様に合っているのでしょうか?

と書きましたが、原因はやはりその 2 点のようです。

どのように直せばいいかと言うと、前者については jsonString をそのまま以下のようにし
て返せばいいです。

// シリアライズ
var jsonString = JsonSerializer.Serialize(eventData, options);

Response.ContentType = "application/json; charset=utf-8";
return Content(jsonString);

後者については、魔界の仮面弁士さんが書かれたように、大文字小文字の問題です。
質問者さんのコードで以下のところのコメントアウトを外せば小文字になります。

// プロパティ名をキャメルケースに変換
//PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

検証に使った GetEvents メソッドのコードを以下に載せておきます。

public ActionResult GetEvents()
{
    var eventData = new List<EventModel>
    {
        new EventModel
        {
            Id = "1",
            Title = "イベント",
            Start = new DateTime(2023,7,2,0,0,0),
            End = new DateTime(2023,7,3,0,0,0)
        },
        new EventModel
        {
            Id = "2",
            Title = "イベント",
            Start = new DateTime(2023,7,4,0,0,0),
            End = new DateTime(2023,7,5,0,0,0)
        }
    };

    // これは日付の JSON 文字列の形式が "\/Date(1688223600000)\/" になるのでダメ
    //return Json(model, JsonRequestBehavior.AllowGet);

    var options = new JsonSerializerOptions
    {
        // 日本語を変換するためのエンコード設定
        Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),

        // プロパティ名をキャメルケースに変換
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

        // インデントを付ける
        WriteIndented = true
    };

    // シリアライズ
    var jsonString = JsonSerializer.Serialize(eventData, options);

    Response.ContentType = "application/json; charset=utf-8";
    return Content(jsonString);
}

引用返信 編集キー/
■102112 / inTopicNo.9)  Re[4]: FullCarendarのイベントソース取得について
□投稿者/ WebSurfer (2726回)-(2023/07/03(Mon) 13:34:48)
No102110 (魔界の仮面弁士 さん) に返信

>>// プロパティ名をキャメルケースに変換
>>//PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
>>と、コメントアウトしてしまった結果そうなります。
>
> PropertyNamingPolicy の問題についてはそれでよいとして、
> 本題の in 演算子のエラーについては、質問事項に記載されていない箇所に
> 問題がありそうですね…。

問題は、質問者さんのコードで、

> var jsonString = JsonSerializer.Serialize(eventData, options);
> return Json(jsonString,JsonRequestBehavior.AllowGet);

としているところのようです。

すなわち C# のオブジェクト List<EventModel> を一行目でJSON 文字列にシリアライズし、
それをさらに二行目でもう一度 JSON 文字列にシリアライズした結果、渡されるデータが
メチャクチャになって、訳の分からないエラーになったということのようです。
引用返信 編集キー/
■102113 / inTopicNo.10)  Re[2]: FullCarendarのイベントソース取得について
□投稿者/ WebSurfer (2727回)-(2023/07/04(Tue) 10:42:37)
No102107 で、

> MVC5 の Json メソッド (Newtonsoft.JSON を使っているはず)

と書きましたが間違ってましたので訂正します。

MVC5 の Json メソッドが使っている JSON シリアライザは JavaScriptSerializer クラスの
ものでした。

JavaScriptSerializer Class
https://learn.microsoft.com/ja-jp/dotnet/api/system.web.script.serialization.javascriptserializer


以下蛇足ですが・・・

JavaScript の Date オブジェクトや .NET Framework の DateTime オブジェクトを JSON で
表すには文字列とする他なく、その形式は使うシリアライザによって異なります。

詳しくは以下の記事を見てください。

日付時刻と JSON 文字列
http://surferonwww.info/BlogEngine/post/2017/08/27/conversion-of-date-or-datetime-to-json-string.aspx

ちなみに、FullCalendar の日付は ISO 8601 形式にする必要があるということで、MVC5 の
Json メソッドではダメでした。


質問者さん>

それを知っていて System.Text.Json 名前空間の JsonSerializer クラスを使ってシリアラ
イズし、さらに JSON の {"name":"value"} の name が小文字で始まらないとダメと言うこ
とで、

PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

を設定したのですかね?

それを分かってるほど知識がある人か、質問にあった 2 重にシリアライズするとかのとんで
もないことをするのはあり得ないと思うのですが、どうなっているんでしょう?
引用返信 編集キー/
■102118 / inTopicNo.11)  Re[3]: FullCarendarのイベントソース取得について
□投稿者/ あああ (7回)-(2023/07/05(Wed) 18:07:40)
色々回答いただきありがとうございます。回答を参考に調べさせていただいたところ、

@フルカレンダーのイベントプロパティについ
仰る通り小文字始まりでないとだめらしく、プロパティ名をキャメルケースに変換して対応いたしました。
コメントアウトしていたのは参考にしたコードでコメントアウトされておりロクに理解もせずにそのままにしておりました。

Ajsonデータのシリアライズについて
テストで文字列を直接返しており、それをモデルをシリアライズして返すように変えたときにreturn句をそのままにしておりました。

B日付フォーマットについて
ISO8601 日付文字列でないとフルカレンダーで認識されなかったのでstringにして無理やり形式を合わせました。

以上を修正したところ正常にイベントがカレンダー上に表示されました。
お忙しいところ時間を割いていただき誠にありがとうございました。
解決済み
引用返信 編集キー/
■102119 / inTopicNo.12)  Re[4]: FullCarendarのイベントソース取得について
□投稿者/ WebSurfer (2729回)-(2023/07/05(Wed) 18:48:52)
No102118 (あああ さん) に返信

> @フルカレンダーのイベントプロパティについ
> 仰る通り小文字始まりでないとだめらしく、プロパティ名をキャメルケースに変換して対応いたしました。
> コメントアウトしていたのは参考にしたコードでコメントアウトされておりロクに理解もせずにそのままにしておりました。
>
> Ajsonデータのシリアライズについて
> テストで文字列を直接返しており、それをモデルをシリアライズして返すように変えたときにreturn句をそのままにしておりました。
>
> B日付フォーマットについて
> ISO8601 日付文字列でないとフルカレンダーで認識されなかったのでstringにして無理やり形式を合わせました。

意味不明ですが、要するに、よく分ってないままあちこちいじりまわして、メチャクチャに
なったコードをそのまま何も考えずに投げてきたと理解します。

もし今後質問する機会があったら、そういうのはやめてください。

また、一番最初に書きましたが、

> 質問者さんの方で切り分けをして、どのあたりに問題がありそうかを調べるというこ
> とはできませんか?
>
> それができる環境を今現在すでに持っていて、今すぐ切り分けができるのは質問者さ
> んだけです。なので、まずは質問者さんの方である程度切り分けしてから、問題の原
> 因と思われる部分だけを提示して質問するようにしましょう。

は質問する前にやってください。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -