Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列化json时如何忽略JsonProperty(PropertyName=";someName";)?_C#_Json_Serialization_Json.net - Fatal编程技术网

C# 序列化json时如何忽略JsonProperty(PropertyName=";someName";)?

C# 序列化json时如何忽略JsonProperty(PropertyName=";someName";)?,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我有一些使用ASP.NETMVC的C#代码,它使用Json.Net来序列化一些DTO。为了减少有效负载,我使用了[JsonProperty(PropertyName=“shortName”)]属性在序列化期间使用更短的属性名 当客户端是另一个.Net应用程序或服务时,这非常有效,因为反序列化使用更长更友好的名称将对象层次结构重新组合在一起,同时保持实际传输负载较低 当客户端通过浏览器使用javascript/ajax时,问题就出现了。它发出请求并获取json。。。但json使用的是不太友好的缩写

我有一些使用ASP.NETMVC的C#代码,它使用Json.Net来序列化一些DTO。为了减少有效负载,我使用了[JsonProperty(PropertyName=“shortName”)]属性在序列化期间使用更短的属性名

当客户端是另一个.Net应用程序或服务时,这非常有效,因为反序列化使用更长更友好的名称将对象层次结构重新组合在一起,同时保持实际传输负载较低

当客户端通过浏览器使用javascript/ajax时,问题就出现了。它发出请求并获取json。。。但json使用的是不太友好的缩写名称

如何使json.net序列化引擎以编程方式忽略[JsonProperty(PropertyName=“shortName”)]属性?理想情况下,我的MVC服务将在那里运行,并且通常使用缩短的属性名进行序列化。当我的代码检测到一个特定参数时,我希望使用较长的名称序列化数据,并忽略[JsonProperty()]属性

有什么建议吗

谢谢


Kevin

这可以使用自定义合同解析器轻松完成。以下是您需要的所有代码:

class LongNameContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        // Let the base class create all the JsonProperties 
        // using the short names
        IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);

        // Now inspect each property and replace the 
        // short name with the real property name
        foreach (JsonProperty prop in list)
        {
            prop.PropertyName = prop.UnderlyingName;
        }

        return list;
    }
}
输出:

--- Using JsonProperty names ---
{
  "cust-num": "BG60938",
  "cust-name": "Bubba Gump Shrimp Company"
}

--- Ignoring JsonProperty names ---
{
  "CustomerNumber": "BG60938",
  "CustomerName": "Bubba Gump Shrimp Company"
}

这可以很容易地使用自定义合同解析器来完成。以下是您需要的所有代码:

class LongNameContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        // Let the base class create all the JsonProperties 
        // using the short names
        IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);

        // Now inspect each property and replace the 
        // short name with the real property name
        foreach (JsonProperty prop in list)
        {
            prop.PropertyName = prop.UnderlyingName;
        }

        return list;
    }
}
输出:

--- Using JsonProperty names ---
{
  "cust-num": "BG60938",
  "cust-name": "Bubba Gump Shrimp Company"
}

--- Ignoring JsonProperty names ---
{
  "CustomerNumber": "BG60938",
  "CustomerName": "Bubba Gump Shrimp Company"
}
只是想用反序列化器类“扩展”Brian的答案

static T Deserialize<T>(string json)
{
    return JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings()
    {
        ContractResolver = new LongNameContractResolver()
    });
}
static T反序列化(字符串json)
{
返回JsonConvert.DeserializeObject(json,新的JsonSerializerSettings()
{
ContractResolver=新的LongNameContractResolver()
});
}
只想用反序列化器类“扩展”Brian的答案

static T Deserialize<T>(string json)
{
    return JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings()
    {
        ContractResolver = new LongNameContractResolver()
    });
}
static T反序列化(字符串json)
{
返回JsonConvert.DeserializeObject(json,新的JsonSerializerSettings()
{
ContractResolver=新的LongNameContractResolver()
});
}

只需删除
JsonProperty
并根据您传递的参数返回一个匿名对象即可。类似于
new{UserName=uname}
我认为最好的方法是创建一个自定义序列化程序(使用json.NET,而不是从头开始)并删除注释。将短名称与长名称作为序列化程序的设置,并在序列化时告诉它所需的名称。json.NET不支持在运行时使用/忽略注释。如果它们在编译时存在,它们将被使用(暴露出一些重大的黑客行为)。我很欣赏这里的评论@evanmcdonnal:如果我们使用自定义序列化程序,我们是否需要在特定于DTO的级别上(连接到每个DTO?)执行此操作?我们有许多DTO,通过我们的许多开发团队跨许多解决方案进行传播。理想情况下,我们可以找到一种相对优雅的方式来连接到序列化过程中,而不必通过主板上的所有DTO访问来接触和维护它。这可以使用自定义契约解析器来完成。请看下面我的答案。@Kevin这要看情况而定,您可以在不更改DTO的情况下以一般方式进行操作。在我的代码库中,在json.NET之上有一些抽象。如果我也这样做,我将在该级别进行更改,并在序列化程序中执行一些操作,例如使用反射获取属性名,然后获取该属性的子字符串以获取短名称。当然,对短名称失去控制是一个小的权衡,但这将是一个简单的通用解决方案。只需删除
JsonProperty
,并根据传递的参数返回一个匿名对象。类似于
new{UserName=uname}
我认为最好的方法是创建一个自定义序列化程序(使用json.NET,而不是从头开始)并删除注释。将短名称与长名称作为序列化程序的设置,并在序列化时告诉它所需的名称。json.NET不支持在运行时使用/忽略注释。如果它们在编译时存在,它们将被使用(暴露出一些重大的黑客行为)。我很欣赏这里的评论@evanmcdonnal:如果我们使用自定义序列化程序,我们是否需要在特定于DTO的级别上(连接到每个DTO?)执行此操作?我们有许多DTO,通过我们的许多开发团队跨许多解决方案进行传播。理想情况下,我们可以找到一种相对优雅的方式来连接到序列化过程中,而不必通过主板上的所有DTO访问来接触和维护它。这可以使用自定义契约解析器来完成。请看下面我的答案。@Kevin这要看情况而定,您可以在不更改DTO的情况下以一般方式进行操作。在我的代码库中,在json.NET之上有一些抽象。如果我也这样做,我将在该级别进行更改,并在序列化程序中执行一些操作,例如使用反射获取属性名,然后获取该属性的子字符串以获取短名称。当然,对短名字失去控制是一个小小的权衡,但这将是一个简单的通用解决方案。来自一位开发伙伴的拥抱:)Tbh我希望有一个更简单的解决方案爱你,布莱恩,这个完美的答案。来自一位开发伙伴的拥抱:)Tbh我希望有一个更简单的解决方案