本文介绍了有条件的DataContract串行化的WebAPI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找到有条件有最好的方法,并从我datacontract连载我的.NET的WebAPI项目中删除属性。在我的API,我想允许用户指定他们希望返回的字段。

I am trying to find the best way to conditionally include and remove properties from my datacontract serialization in my .net WebApi project. In my Api, I want to allow users to specify the fields that they want returned.

例如,假设我希望我的API返回下面的类的实例。

For example, assume I want my API to return an instance of the following class.

public class Car
{
    public int Id { get; set; }
    public string Year { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string Color { get; set; }
}

而不是请求整个对象

不过,API调用想要的标识,只有让现场。因此,返回JSON是

But instead of requesting the entire object, the API call wants the Id and Make field only. So the return JSON would be

 { "Id": 12345, "Make": "Ford"}

代替整个对象。

instead of the entire object.

有没有用DataContract串行的方式,我可以有条件地添加和删除我返回对象的属性?

Is there a way with the DataContract Serializer that I can conditionally add and remove properties from my return object?

**编辑我已经看过了IgnoreDefault财产,我不相信它会做正是我需要的。问题是,我想包括和排除基于API请求性质,不一定对他们是否有数据。

**EDITI have looked at the IgnoreDefault property, and I don't believe it will do exactly what I need. The problem is that I want to include and exclude properties based on an api request, not necessarily on whether or not they have data.

是否有某种方式挂接到反序列化过程并跳过某些属性?我可以做一些定制的合约?

Is there some way to hook into the deserialization process and skip certain properties? Can I do some kind of custom contract?

推荐答案

如果您使用的是的DataContractSerializer (或者,在这种情况下, DataContractJsonSerializer ),您可以使用数据成员(EmitDefaultValue = FALSE)] 装饰类。通过这种方式,你可以设置你的属性不的希望序列化到它们的默认值(即字符串,0为整数,并等等),以及他们将不

If you're using the DataContractSerializer (or, in this case, the DataContractJsonSerializer), you can use the DataMember(EmitDefaultValue = false)] decoration in your class. This way, you can set the properties which you don't want serialized to their default values (i.e., null for strings, 0 for ints and so on), and they won't be.

如果您正在使用ASP.NET Web API,那么你就应该知道,默认的JSON序列不是 DataContractJsonSerializer (DCJS),但JSON。 NET代替。所以,除非你明确地配置您的 JsonMediaTypeFormatter 来使用DCJS,你需要另一个属性来获得相同的行为( JsonProperty ,和其 DefaultValueHandling 属性)。

If you're using the ASP.NET Web API, then you should be aware that the default JSON serializer isn't the DataContractJsonSerializer (DCJS), but JSON.NET instead. So unless you explicitly configure your JsonMediaTypeFormatter to use DCJS, you need another attribute to get the same behavior (JsonProperty, and its DefaultValueHandling property).

只有以下的code连载这是该Car对象分配的两个成员,同时使用串行。请注意,您可以删除的属性之一,如果你只打算使用其中的一个。

The code below only serializes the two members which were assigned in this Car object, using both serializers. Notice that you can remove one of the attributes if you're only going to use one of them.

public class StackOverflow_12465285
{
    [DataContract]
    public class Car
    {
        private int savedId;
        private string savedYear;
        private string savedMake;
        private string savedModel;
        private string savedColor;

        [DataMember(EmitDefaultValue = false)]
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
        public int Id { get; set; }
        [DataMember(EmitDefaultValue = false)]
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Year { get; set; }
        [DataMember(EmitDefaultValue = false)]
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Make { get; set; }
        [DataMember(EmitDefaultValue = false)]
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Model { get; set; }
        [DataMember(EmitDefaultValue = false)]
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Color { get; set; }

        [OnSerializing]
        void OnSerializing(StreamingContext ctx)
        {
            this.savedId = this.Id;
            this.savedYear = this.Year;
            this.savedMake = this.Make;
            this.savedModel = this.Model;
            this.savedColor = this.Color;

            // Logic to determine which ones to serialize, let's say I only want Id, Make; so make all others default.
            this.Color = default(string);
            this.Model = default(string);
            this.Year = default(string);
        }

        [OnSerialized]
        void OnSerialized(StreamingContext ctx)
        {
            this.Id = this.savedId;
            this.Year = this.savedYear;
            this.Make = this.savedMake;
            this.Model = this.savedModel;
            this.Color = this.savedColor;
        }
    }

    public static void Test()
    {
        Car car = new Car { Id = 12345, Make = "Ford", Model = "Focus", Color = "Red", Year = "2010" };
        JsonSerializer js = new JsonSerializer();
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        js.Serialize(sw, car);
        Console.WriteLine("Using JSON.NET: {0}", sb.ToString());

        MemoryStream ms = new MemoryStream();
        DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(Car));
        dcjs.WriteObject(ms, car);
        Console.WriteLine("Using DCJS: {0}", Encoding.UTF8.GetString(ms.ToArray()));
    }
}

这篇关于有条件的DataContract串行化的WebAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 14:19