使用JSON.Net序列化数据的问题

时间:2016-11-18 23:54:00

标签: c# asp.net-mvc kendo-ui json.net kendo-scheduler

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

    [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:

{  
   "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文件中,我有以下几行:

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

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

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

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正确地序列化我的名字只是为了这个方法或者是否有一些我可以在我的视图模型中使用的其他属性来使名称序列化正确或者在剑道中有一个设置是否允许剑道使用驼峰格式?

1 个答案:

答案 0 :(得分:4)

如果您使用的是Json.NET 9.0.1或更高版本,则可以使用naming strategy标记特定类型的[JsonObject(NamingStrategyType = typeof(TNamingStrategy))]。这会覆盖CamelCasePropertyNamesContractResolver的命名策略。在您的情况下,您需要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")]属性。

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