我想我的序列化类的所有属性,但要隐藏某些属性,同时返回响应。
我使用NewtonSoft.Json.Net用于序列。
例如,在下面的类我想序列两种特性,但我只想要回地名。
有没有办法做到这一点?
[DataContract]
public class Place
{
[DataMember(EmitDefaultValue = false)]
public int PlaceId { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public string PlaceName { get; set; }
}
编辑1:
下面是我当前的JSON文件。
[
{
"placeId": 1,
"placeName": "Malacca"
},
{
"placeId": 2,
"placeName": "Kuala Lumpur"
},
{
"placeId": 3,
"placeName": "Genting Highlands"
},
{
"placeId": 4,
"placeName": "Singapore"
},
{
"placeId": 5,
"placeName": "Penang"
},
{
"placeId": 6,
"placeName": "Perak"
},
{
"placeId": 8,
"placeName": "Selangor"
}
]
编辑2:找到的解
我发现有一些研究解决方案。
我创建了一个自定义的合同解析器序列化和反序列化的所有属性,并通过它。
下面是我的代码
public class AllPropertiesResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
property.Ignored = false;
return property;
}
}
而下面是我把它称为代码。
JsonConvert.SerializeObject(object, new JsonSerializerSettings() { ContractResolver = new AllPropertiesResolver() });
JsonConvert.DeserializeObject<T>(stream, new JsonSerializerSettings() { ContractResolver = new AllPropertiesResolver() });
谢谢大家的响应。
您可以使用[JsonIgnore]
既然你标记你的问题asp.net-web-api
我想你使用它。 所以下面是一个例子,其中,控制器将返回整个模型,除了与属性JsonIgnore
。 通过使用自定义ContractResolver
我们序列化器它包括所有的属性(即使他们得到了JsonIgnore
)。 而使用默认ContractResolver
返回我们的反应时。
但要注意,它会覆盖默认行为。 所以,你可能要添加一些其他的检查,不仅仅是设置Ignored = false
;
public class PlaceController : ApiController
{
[HttpGet]
public IHttpActionResult Get()
{
var json = "[{\"placeId\": 1,\"placeName\": \"Malacca\"},{\"placeId\": 2,\"placeName\": \"Kuala Lumpur\"},{\"placeId\": 3,\"placeName\": \"Genting Highlands\"},{\"placeId\": 4,\"placeName\": \"Singapore\"},{\"placeId\": 5,\"placeName\": \"Penang\"},{\"placeId\": 6,\"placeName\": \"Perak\"},{\"placeId\": 8,\"placeName\": \"Selangor\"}]";
var settings = new JsonSerializerSettings();
settings.ContractResolver = new IncludeAllPropertiesContractResolver();
var places = JsonConvert.DeserializeObject<Place[]>(json, settings);
return Ok(places);
}
}
public class IncludeAllPropertiesContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
// Or other way to determine...
foreach (var jsonProperty in properties)
{
// Include all properties.
jsonProperty.Ignored = false;
}
return properties;
}
}
[DataContract]
public class Place
{
[JsonIgnore]
[DataMember(EmitDefaultValue = false)]
public int PlaceId { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public string PlaceName { get; set; }
}
输出:
[
{
"placeName": "Malacca"
},
{
"placeName": "Kuala Lumpur"
},
{
"placeName": "Genting Highlands"
},
{
"placeName": "Singapore"
},
{
"placeName": "Penang"
},
{
"placeName": "Perak"
},
{
"placeName": "Selangor"
}
]
或者,如果你不介意一点点思考。 下面我们用一个JsonInclude
-attribute,这将覆盖的默认行为JsonIgnore
。
public class JsonIncludeContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
var actualProperties = type.GetProperties();
foreach (var jsonProperty in properties)
{
// Check if it got our JsonInclude attribute.
var property = actualProperties.FirstOrDefault(x => x.Name == jsonProperty.PropertyName);
if (property != null && property.GetCustomAttribute(typeof(JsonInclude)) != null)
{
jsonProperty.Ignored = false;
}
}
return properties;
}
}
[DataContract]
public class Place
{
[JsonInclude] // Will override JsonIgnore.
[JsonIgnore]
[DataMember(EmitDefaultValue = false)]
public int PlaceId { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public string PlaceName { get; set; }
}
public class JsonInclude : Attribute
{
}
一个可能的解决方法是使用匿名类: return new { PlaceName = place.PlaceName };
。
另一种解决方案是创建你自己的序列为您的类型和使用它的类型。 例如,对于自定义序列化,你可以找到在这里
如果您JSON输出是一个List<Place>
你可以试试:
var json = "[{\"placeId\":1,\"placeName\":\"Malacca\"},{\"placeId\":2,\"placeName\":\"Kuala Lumpur\"},{\"placeId\":3,\"placeName\":\"Genting Highlands\"},{\"placeId\":4,\"placeName\":\"Singapore\"},{\"placeId\":5,\"placeName\":\"Penang\"},{\"placeId\":6,\"placeName\":\"Perak\"},{\"placeId\":8,\"placeName\":\"Selangor\"}]";
var Places = JsonConvert.DeserializeObject<List<Place>>(json);
foreach (var place in Places)
{
Console.WriteLine(place.PlaceName);
}
文章来源: Custom Json Serializer to serialize and deserialize all properties by ignoring the class attributes