Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

prevent property from being serialized in web API

People also ask

How can you prevent a property from being serialized?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

How to ignore some property in Json response c#?

To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.

What is the use of Ignoredatamember in Web API?

NET Core Web Api. When applied to the member of a type, specifies that the member is not part of a data contract and is not serialized. You can fill the id later on in the controller and still maintain one viewmodel.

What is serialization in Web API?

The Web API serializes all the public properties into JSON. In the older versions of Web API, the default serialization property was in PascalCase. When we are working with . NET based applications, the casing doesn't matter.


ASP.NET Web API uses Json.Net as default formatter, so if your application just only uses JSON as data format, you can use [JsonIgnore] to ignore property for serialization:

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonIgnore]
    public List<Something> Somethings { get; set; }
}

But, this way does not support XML format. So, in case your application has to support XML format more (or only support XML), instead of using Json.Net, you should use [DataContract] which supports both JSON and XML:

[DataContract]
public class Foo
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string Name { get; set; }

    //Ignore by default
    public List<Something> Somethings { get; set; }
}

For more understanding, you can read the official article.


According to the Web API documentation page JSON and XML Serialization in ASP.NET Web API to explicitly prevent serialization on a property you can either use [JsonIgnore] for the Json serializer or [IgnoreDataMember] for the default XML serializer.

However in testing I have noticed that [IgnoreDataMember] prevents serialization for both XML and Json requests, so I would recommend using that rather than decorating a property with multiple attributes.


Instead of letting everything get serialized by default, you can take the "opt-in" approach. In this scenario, only the properties you specify are allowed to be serialized. You do this with the DataContractAttribute and DataMemberAttribute, found in the System.Runtime.Serialization namespace.

The DataContactAttribute is applied to the class, and the DataMemberAttribute is applied to each member you want to be serialized:

[DataContract]
public class MyClass {

  [DataMember]
  public int Id { get; set;} // Serialized

  [DataMember]
  public string Name { get; set; } // Serialized

  public string DontExposeMe { get; set; } // Will not be serialized
}

Dare I say this is a better approach because it forces you to make explicit decisions about what will or will not make it through serialization. It also allows your model classes to live in a project by themselves, without taking a dependency on JSON.net just because somewhere else you happen to be serializing them with JSON.net.


This worked for me: Create a custom contract resolver which has a public property called AllowList of string array type. In your action, modify that property depending on what the action needs to return.

1. create a custom contract resolver:

public class PublicDomainJsonContractResolverOptIn : DefaultContractResolver
{
    public string[] AllowList { get; set; }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);

        properties = properties.Where(p => AllowList.Contains(p.PropertyName)).ToList();
        return properties;
    }
}

2. use custom contract resolver in action

[HttpGet]
public BinaryImage Single(int key)
{
    //limit properties that are sent on wire for this request specifically
    var contractResolver = Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver as PublicDomainJsonContractResolverOptIn;
    if (contractResolver != null)
        contractResolver.AllowList = new string[] { "Id", "Bytes", "MimeType", "Width", "Height" };

    BinaryImage image = new BinaryImage { Id = 1 };
    //etc. etc.
    return image;
}

This approach allowed me to allow/disallow for specific request instead of modifying the class definition. And if you don't need XML serialization, don't forget to turn it off in your App_Start\WebApiConfig.cs or your API will return blocked properties if the client requests xml instead of json.

//remove xml serialization
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

I will show you 2 ways to accomplish what you want:

First way: Decorate your field with JsonProperty attribute in order to skip the serialization of that field if it is null.

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public List<Something> Somethings { get; set; }
}

Second way: If you are negotiation with some complex scenarios then you could use the Web Api convention ("ShouldSerialize") in order to skip serialization of that field depending of some specific logic.

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }

    public List<Something> Somethings { get; set; }

    public bool ShouldSerializeSomethings() {
         var resultOfSomeLogic = false;
         return resultOfSomeLogic; 
    }
}

WebApi uses JSON.Net and it use reflection to serialization so when it has detected (for instance) the ShouldSerializeFieldX() method the field with name FieldX will not be serialized.