使用JSON.Net序列化数据的问题 [英] Issue with serializing data using JSON.Net

查看:77
本文介绍了使用JSON.Net序列化数据的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用Kendo Scheduler,以使用Web Api从数据库中提取数据.我创建了一个Web Api函数,并对其中的一些数据进行了硬编码,以确保Kendo Scheduler可以读取我的数据.这是我的Api函数代码:

I am using a Kendo Scheduler in my app to pull data from my database using a Web Api. I created a Web Api function and just hard coded some data in there to be sure the Kendo Scheduler could read my data. Here is my code for the Api function:

    [Route("api/v1/Events/GetPersonalEvents", Name = "ApiEventsGetPersonalEvents")]
    [HttpGet]
    public DataSourceResult GetPersonalEvents([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))]DataSourceRequest request)
    {
        var q = new ViewModels.Events.EventViewModel();
        q.Id = 1;
        q.Title = "This is a test";
        q.Start = DateTime.Now;
        q.End = DateTime.Now.AddHours(1);
        q.Description = "Test entry";

        var list = new List<ViewModels.Events.EventViewModel>();
        list.Add(q);
        return list.ToDataSourceResult(request);
    }

Kendo Scheduler在日历上未显示任何内容.使用Fiddler,我可以看到Kendo Scheduler正在调用我的API,而我的API正在返回数据.这是要发送的JSON:

The Kendo Scheduler was not showing anything on the calendar. Using Fiddler, I was able to see that Kendo Scheduler was calling my API and my API was returning data. Here is the JSON getting sent:

{  
   "data":[  
      {  
         "id":1,
         "title":"This is a test",
         "description":"Test entry",
         "isAllDay":false,
         "start":"2016-11-18T15:31:33.1173519-08:00",
         "end":"2016-11-18T16:31:33.1178524-08:00",
         "startTimezone":null,
         "endTimezone":null,
         "recurrenceRule":null,
         "recurrenceException":null
      }
   ],
   "total":1,
   "aggregateResults":null,
   "errors":null
}

一切似乎都正常.经过进一步调查,我终于弄清楚了我的问题.在我的global.asax.cs文件中,这些行如下:

Everything seemed to be working fine. Upon further investigation, I finally figured out my issue. In my global.asax.cs file I have these lines:

HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;

这是什么导致JSON.Net自动将C#名称转换为对Javascript友好的名称(例如Title变为titleDescription变为description等),这就是我想.但是,剑道显然要求其名称类似于C#(例如Title而不是title).我通过注释global.asax.cs文件中的那三行来验证这一点,一切正常.

What this does is it causes JSON.Net to automatically convert C# names to Javascript-friendly names (e.g. Title becomes title, Description becomes description, etc...), which is what I want. However, Kendo, apparently, requires the names to be like C# (e.g. Title instead of title). I verified this by commenting out those three lines in my global.asax.cs file and everything worked fine.

所以,然后我将注意力转向了我的ViewModel.我用JsonProperty属性装饰了我的属性,并指定了一个特定的名称.但是,它仍被序列化为小写名称.这是视图模型代码:

So, then I turned my attention to my ViewModel. I decorated my properties with the JsonProperty attribute, specifying a specific name. However, it's still being serialized as lower case names. Here is the view model code:

public class EventViewModel : ISchedulerEvent
{
    [JsonProperty(PropertyName = "Id")]
    public int Id { get; set; }

    [JsonProperty(PropertyName = "Title")]
    public string Title { get; set; }

    [JsonProperty(PropertyName = "Description")]
    public string Description { get; set; }

    [JsonProperty(PropertyName = "IsAllDay")]
    public bool IsAllDay { get; set; }

    [JsonProperty(PropertyName = "Start")]
    public DateTime Start { get; set; }

    [JsonProperty(PropertyName = "End")]
    public DateTime End { get; set; }

    [JsonProperty(PropertyName = "StartTimezone")]
    public string StartTimezone { get; set; }

    [JsonProperty(PropertyName = "EndTimezone")]
    public string EndTimezone { get; set; }

    [JsonProperty(PropertyName = "RecurrenceRule")]
    public string RecurrenceRule { get; set; }

    [JsonProperty(PropertyName = "RecurrenceException")]
    public string RecurrenceException { get; set; }
}

所以现在我没主意了.因此,有没有一种方法可以使Json.Net仅为此方法正确地序列化我的名称,或者是否可以在我的视图模型中使用其他属性来使名称正确序列化,或者Kendo中是否有设置会允许剑道使用驼峰式保护套格式?

So now I am out of ideas. So is there a way to either a way to make Json.Net serialize my names properly JUST for this one method or is there some other attribute I can use in my view model to make the names serialize correctly or is there a setting in Kendo that would allow Kendo to use the camel case format?

推荐答案

如果您使用的是Json.NET 9.0.1或更高版本,则可以指定 DefaultNamingStrategy :

If you are using Json.NET 9.0.1 or later, you can specify a naming strategy for a specific type by marking it with [JsonObject(NamingStrategyType = typeof(TNamingStrategy))]. This overrides the naming strategy of CamelCasePropertyNamesContractResolver. In your case you want DefaultNamingStrategy:

[JsonObject(NamingStrategyType = typeof(DefaultNamingStrategy))]
public class EventViewModel
{
    public int Id { get; set; }

    public string Title { get; set; }

    public string Description { get; set; }

    public bool IsAllDay { get; set; }

    public DateTime Start { get; set; }

    public DateTime End { get; set; }

    public string StartTimezone { get; set; }

    public string EndTimezone { get; set; }

    public string RecurrenceRule { get; set; }

    public string RecurrenceException { get; set; }
}

请注意,不再需要[JsonProperty("name")]属性.

Note that the [JsonProperty("name")] attributes are no longer needed.

在您的全球合同解析器中,还有一个属性 NamingStrategy .将 NamingStrategy.OverrideSpecifiedNames 设置为false也会阻止[JsonProperty("name")]名称不被全球覆盖.对于CamelCasePropertyNamesContractResolver,似乎默认值为true,这是导致问题的原因.

On your global contract resolver, there is also a property NamingStrategy. Setting NamingStrategy.OverrideSpecifiedNames to false also prevents [JsonProperty("name")] names from being overridden globally. For CamelCasePropertyNamesContractResolver it seems the default is true, which is the cause of your problem.

这篇关于使用JSON.Net序列化数据的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆