FullCalendar(v4)无法使用有效的JSON

时间:2019-08-30 10:29:47

标签: json asp.net-mvc fullcalendar fullcalendar-4

我希望有人可以在使用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和COS信息:

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\"}]"

1 个答案:

答案 0 :(得分: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);
    }

P.S。您正在使用哪个版本的MVC?无论如何,受支持的最新版本还是使用JSON.NET作为默认序列化程序,因此应该没有理由手动进行此操作。如果您使用的是较旧版本的MVC(由于它会生成诸如Date(1567062000000)\之类的奇数日期格式而看起来可能具有该版本),并且由于某种原因而无法升级,则默认情况下为ways to make it use JSON.NET。另外,您可以使用JSON.NET自己进行序列化,然后仅从操作方法返回纯字符串。

P.P.S。上述方法的另一种替代方法是在fullCalendar中使用momentJS plugin,然后允许您使用momentJS解析您的日期-并且momentJS包含ability to parse ASP.NET's old date format