如何在我的JSON模型类中使用保留关键字作为标识符?

时间:2013-05-23 02:32:55

标签: c# .net asp.net-mvc asp.net-web-api

我之前从未使用过Web API,但我需要一个接受/返回JSON对象的Web服务,并且使用它似乎是一个合理的事情。它看起来很简单(如果不是为了我的目的有点过分),但我需要处理的数据结构看起来像:

{
    "values":["foo", "bar"],
    "default":"bar"
}

所以我去制作一个Model对象:

class DropDownValues {
    public string[] values { get; set; }
    public string default { get; set; }
}

问题是默认似乎是受保护的关键字。必须有一些方法来解决这个问题,对吗?

3 个答案:

答案 0 :(得分:12)

您可以在C#中使用关键字作为标识符,方法是在它们前面添加@。

答案 1 :(得分:9)

我建议采取不同的方式。保持您的C#对象模型尽可能标准(我不会使用@符号和C# keywords作为属性名称)

我们可以通过使用Json.NET功能来分离序列化(JSON)世界和C#对象。

最简单的方法之一是使用属性装饰:

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

在这种情况下,我们必须在项目中引用Newtonsoft.Json。如果它必须是POCO,我们可以介绍来自CustomResolver的{​​{1}}并在那里定义这些转换...

但在这种情况下,关注点的分离是一个更纯粹的解决方案,我想说

编辑:JSON合同解析程序草稿 (请参阅评论)

重要说明:Newtonsoft.Json是Web API的一部分。它不仅是一个开源的,甚至MS团队都认为它是一个核心的JSON序列化器。

1)Newtonsoft.Json(作为Web.API的一部分)已经安装在您的解决方案中。所以你不必单独下载(nuget)。它始终位于您的DefaultContractResolver文件夹中。因此,使用该属性只是添加引用。它就在那里......

2)有一个小草案如何做属性的东西,同时保持POCO 。正如我在此尝试解释的那样:POCO's, behavior and Peristance Igorance,为了保持POCO(例如我们从数据层上的NHibernate分层架构中获利),我们可以用{{1} 替换属性}。我们的POCO库不需要引用任何东西

我们只需要扩展服务层:

packages

这样我们就像Contract Resolver一样向 serailizer 提供了相同的信息。

现在,我们必须使用它。有很多方法(例如全局),但我们只能为控制器执行此操作:

public class MyResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(
         MemberInfo member,
         MemberSerialization memberSerialization)
    {

        var jProperty = base.CreateProperty(member, memberSerialization);

        var propertyInfo = member as PropertyInfo;
        if (propertyInfo == null)
        {
            return jProperty;
        }

        // just adjust in case if Property name is DefaultValue
        var isDefaultValueProeprty =
                  propertyInfo.Name.Equals("DefaultValue");

        if(isDefaultValueProeprty)
        {
            jProperty.PropertyName = "default";
        }

        return jProperty;
    }
    ...

答案 2 :(得分:3)

使用camel约定的类DropDownValues

class DropDownValues {
    public string[] values { get; set; }
    public string default { get; set; }
}

您可以使用前缀@来传递,但它仍然没有遵循C#编码惯例。

您可以避免使用保留关键字并仍使用C#编码约定的更好解决方案是使用CamelCasePropertyNamesContractResolver

class DropDownValues {
    public string[] Values { get; set; }
    public string Default { get; set; }
}

并自定义JsonFormatter以避免C#和json对象之间的约定不匹配,如下所示:

var jsonFormatter = configuration.Formatters.JsonFormatter;
jsonFormatter.SerializerSettings = new JsonSerializerSettings()
{  
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};