コントローラー メソッドの戻り値の型がインターフェイスの場合は、アクション フィルターを適用して、インターフェイス プロパティのみをシリアル化することもできます。このようにして、インターフェイスを実装するクラスの属性を変更しなくても、常にインターフェイス定義との同期を保つことができます。
このためには、最初にここでInterfaceContractResolver
説明されているように、カスタム コントラクト リゾルバーを作成する必要があります。
public class InterfaceContractResolver : DefaultContractResolver
{
private readonly Type _interfaceType;
public InterfaceContractResolver(Type interfaceType)
{
_interfaceType = interfaceType;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(_interfaceType, memberSerialization);
return properties;
}
}
次に、コントローラー メソッドの戻り値の型を調べ、それがインターフェイスの場合は上で定義したコントラクト リゾルバーを使用するアクション フィルターを (ここで説明されているように属性として、またはこれをデフォルトの動作として使用する場合はグローバルに)追加します。
public class InterfaceFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
ObjectContent content = actionExecutedContext.Response.Content as ObjectContent;
if (content != null)
{
Type returnType = actionExecutedContext.ActionContext.ActionDescriptor.ReturnType;
if (returnType.IsInterface && content.Formatter is JsonMediaTypeFormatter)
{
var formatter = new JsonMediaTypeFormatter
{
SerializerSettings =
{
ContractResolver = new InterfaceContractResolver(returnType)
}
};
actionExecutedContext.Response.Content = new ObjectContent(content.ObjectType, content.Value, formatter);
}
}
}
}