0

我希望有人可以在使用 Json 选项时帮助 FullCalendar (v4) 不加载事件。当相同的数据被硬编码为事件时,它可以正常工作。

生成的 Json 是有效的 - 即它通过https://jsoncompare.com进行验证

我花了很多时间试图自己解决这个问题,但我碰壁了——所以有时间寻求帮助。

我尝试过使用内置的 Net Json 序列化程序——但这会产生错误的日​​期格式,所以我也尝试了 newtonsoft Json.net,它确实为 FullCallendar 产生了正确的日期格式,但仍然不会加载事件。

使用 JSON 时没有 JS 控制台错误,它根本不会加载到日历中。JSON 来自同一个域(即不受跨域问题的影响)。

非常欢迎任何帮助/建议,谢谢。

当事件被硬编码时,这非常有效:

var calendar = new FullCalendar.Calendar(calendarEl,
                {
                    plugins: ['interaction', 'dayGrid', 'timeGrid'],
                    defaultDate: new Date(),
                    defaultView: 'timeGridWeek',
                    minTime: '07:00:00',
                    maxTime: '22:00:00',
                    timeZone: 'local',
                    header: {
                        left: 'prev,next today',
                        center: 'title',
                        right: 'timeGridDay,timeGridWeek,dayGridMonth'
                    },
                    events: [ //hardcoded events load just fine
                            {
                                id: '12',
                                title: 'Event Name',
                                start: '2019-08-28T08:00:00',
                                end: '2019-08-28T08:30:00'
                            }
                        ]

                });

            calendar.render();

        }

使用 JSON 选项时,它不起作用:

//JSON provided events do not load
events: {
          url:'/CourseTimetable/GetAllEventsAsJson' 
         }

提供提要的另一种方式(不带大括号和“url:”前缀):

events:'/CourseTimetable/GetAllEventsAsJson' 

URL 工作正常 - 验证为 JSON - 并且不会产生任何错误 - 它产生:

"[{\"id\":12,\"title\":\"Event 1\",\"start\":\"2019-08-29T08:00:00\",\"end\":\"2019-08-29T08:30:00\"}]"

HEADER 和 cors 信息:

Content-Type: application/json; charset=utf-8
Referer: http://localhost:54928/CourseTimetable
Request Method: GET
Status Code: 200 OK

Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin

提前感谢您的任何帮助/建议:)

这是两个替代控制器版本(使用标准 .net,然后使用 json.net)

标准.net

 public JsonResult GetAllEventsAsJson(DateTime? start = null, DateTime? end = null)
        {

            var events = db.CourseTimetables.Where(p => p.StartTime >= start && p.EndTime <= end)
                .Select(s => new
                {
                    id = s.Id,
                    title = s.Title,
                    start = s.StartTime,
                    end = s.EndTime
                }).ToList();

            //using built in .NET serialiser
            return new JsonResult { Data = events, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

上述操作的输出(主要区别是输出日期和转义):

[{"id":12,"title":"Event 1","start":"\/Date(1567062000000)\/","end":"\/Date(1567063800000)\/"},{"id":13,"title":"Event 2","start":"\/Date(1567148400000)\/","end":"\/Date(1567150200000)\/"}]

json.net版

 public ActionResult GetAllEventsAsJson(DateTime? start = null, DateTime? end = null)
        {

            var events = db.CourseTimetables.Where(p => p.StartTime >= start && p.EndTime <= end)
                .Select(s => new
                {
                    id = s.Id,
                    title = s.Title,
                    start = s.StartTime,
                    end = s.EndTime
                }).ToList();

            //USING JSON.NET
            string jsonData = JsonConvert.SerializeObject(events);
            return Json(jsonData, JsonRequestBehavior.AllowGet);
        }

上述操作的输出(日期采用正确的 iso 格式):

"[{\"id\":12,\"title\":\"Event 1\",\"start\":\"2019-08-29T08:00:00\",\"end\":\"2019-08-29T08:30:00\"},{\"id\":13,\"title\":\"Event 2\",\"start\":\"2019-08-30T08:00:00\",\"end\":\"2019-08-30T08:30:00\"}]"
4

1 回答 1

0

这种格式:"[{\"id\":12,\"title\":\"Event 1\",\"start\":\...等是问题所在。您正在对数据进行双重序列化。看到那些外引号 ( ") 和斜线了\吗?外部引号表示您正在返回一个简单的字符串作为响应(这有效的 JSON,但解析器会将其视为纯文本),斜线是必须对字符串中的引号进行转义的结果。因此,虽然内部数据看起来像 JSON,但客户端解析器不会将其视为 JSON。相反,整个事情只是被视为一个大字符串,其中没有对象、属性等。

在 ASP.NET MVC 中,return Json...期望您为它提供一个对象。然后它会自动为您将其序列化为 JSON。你不需要在传入之前对其进行序列化。只需删除该代码并events直接发送到Json()方法:

public ActionResult GetAllEventsAsJson(DateTime? start = null, DateTime? end = null)
{
        var events = db.CourseTimetables.Where(p => p.StartTime >= start && p.EndTime <= end)
            .Select(s => new
            {
                id = s.Id,
                title = s.Title,
                start = s.StartTime,
                end = s.EndTime
            }).ToList();

        return Json(events, JsonRequestBehavior.AllowGet);
    }

PS你使用的是什么版本的MVC?较新的受支持版本无论如何都使用 JSON.NET 作为默认序列化程序,因此没有理由必须手动执行此操作。如果你有一个旧版本的 MVC(看起来你可能有,因为它产生了那些奇怪的日期格式,例如Date(1567062000000)\)并且由于某种原因无法升级,有办法让它默认使用 JSON.NET。或者,您可以使用 JSON.NET 自己进行序列化,然后从您的操作方法中返回一个纯字符串。

PPS 上面的另一个替代方法是在 fullCalendar 中使用momentJS 插件,然后允许您使用 momentJS 来解析日期 - 而 momentJS 包括解析 ASP.NET 旧日期格式的能力

于 2019-08-30T13:54:56.473 回答