In this tutorial, you will learn how to filter out content-type properties that you do not want to be exposed via the content delivery API. When building any website performance and security are both important drivers that you need to consider. Having an end-point that exposes unused data is bad practice. Requests to the API will take slightly longer to process. More data will need to be transmitted from the server. The requesting applications will also be affected as it will increase the time required to parse data. By reducing the payload of your API, by say 20%, you would notice a performance gain. Depending on the API, exposing data to would-be hackers is also sub-optimal. Your APIs should be designed to be laser-focused. Only exposing the bare minimum amounts of data the requester will need. It does not matter if you are trying to expose a page or a block from the content delivery API you will need to consider what you are exposing.

Episerver attributes are used extensively to define meta-data and validations. Out-of-the-box, Episerver supports the JsonIgnoreAttribute that comes with JSON.NET. You should apply this attribute to all properties on your page and block types that you do not want to be exposed from the content delivery API. For example, imagine you had a settings page. A settings page could contain a mix of properties, some being sensitive data, while others should be publicly accessible. Without filtering the sensitive properties from the content delivery API, you will be in for trouble! If you adopt the homepage settings pattern then this is an issue you will encounter on your project which you will need to solve!

Out-of-the-box, Episerver relies on the JsonIgnoreAttribute attribute for filtering out properties from content delivery API. I do not think that is not very intuitive. Coming across JsonIgnoreAttribute in code does not intentionally express that it is related to the content delivery API output. To make it a little more obvious within your codebase about what is going on, you could consider defining a custom attribute and creating your own filtering system. Sound interesting? Read on to learn more!

Custom Filtering in the Episerver Content Delivery API

I think that JsonIgnoreAttribute attribute in this context is not very declarative. It does not intentionally express what you are doing. To make the code more intuitive, you could go with a custom solution. The benefit of a custom solution is the ability to be more declarative within your code and the ability to customise the rules to suit your needs. If this sounds good, the first step is to define a custom attribute:

This is step one done. In the next step, we will create a custom ContentModelMapperBase to filter properties that have been decorated with our custom attribute form being returned in the content delivery API. The purpose of a content model mapper is to tell the Episerver pipeline how to serialize Episerver content into JSON. Inheriting from the content mapper base class is not the only way to define serialization rules. As shown in the music festival sample site, you could create a class that implements the IContentModelMapper instead. If you want to limit the properties returned by the content deliver API within the model mapper, you can make use of ShouldPropertyBeIgnored:

With a custom model mapper defined, it now needs to be registered with Episerver. This is done by registering it with StructureMap, within ConfigureContainer(). See here for more information on how to do this:

With the mapper registered, decorating a property on a page (or block) will stop that property from being returned whenever a content delivery API call is made. You may be thinking that this is a lot of effort for a small nit-pick, maybe it is? If you want to provide some more advanced property filtering, it is fairly easy to extend what we have built above to cater for more advanced scenarios! If you want to checkout how the default Episerver behaviour works, you can use DotPeek to look within EPiServer.ContentApi.Core.Serialization at the ShouldPropertyBeIgnored. Enjoy!