Table of Contents

Class ExpandPolicy

Namespace
Breeze.Core
Assembly
Breeze.Core.dll

Which navigation properties a client may expand from each entity type.

public static class ExpandPolicy
Inheritance
ExpandPolicy
Inherited Members

Remarks

Rules come from two places: AllowExpandAttribute and DenyExpandAttribute on the entity type, and the Allow<T>(params Expression<Func<T, object?>>[]) and Deny<T>(params Expression<Func<T, object?>>[]) methods here. The methods exist because a generated or scaffolded model cannot carry attributes - and because a registration overrides the attributes, so a deployment can tighten or relax what the model declares without editing it.

Each navigation is judged by this ladder, highest first:

  1. a registered Deny<T>(params Expression<Func<T, object?>>[]) refuses it;
  2. a registered Allow<T>(params Expression<Func<T, object?>>[]) list permits exactly its members and refuses everything else, shadowing the type's attributes entirely;
  3. a DenyExpandAttribute refuses it;
  4. an AllowExpandAttribute list permits exactly its members;
  5. otherwise DenyByDefault decides.

An allow-list always means "these and no others", whichever source it came from. So Allow<Order>(o => o.Employee) does not merely lift a DenyExpand on Employee - it makes Employee the only navigation expandable from Order.

With no rules at all nothing is refused, so adding this to an existing application changes nothing until you declare something or set DenyByDefault.

This governs expand only. A client can still reach a related entity through select, which is checked by MaxDepth but not by this policy.

Properties

DenyByDefault

Whether a navigation with no rule about it is refused. False by default, so an existing application is unaffected until it opts in.

public static bool DenyByDefault { get; set; }

Property Value

bool

Remarks

Setting this true makes every expandable navigation something you declared on purpose, which is the safer arrangement but needs the whole model reviewed first.

Methods

Allow<T>(params Expression<Func<T, object?>>[])

Permit exactly these navigations on T, refusing every other one.

public static void Allow<T>(params Expression<Func<T, object?>>[] navigations)

Parameters

navigations Expression<Func<T, object>>[]

Property expressions, as in c => c.Orders.

Type Parameters

T

The entity type the navigations are declared on.

Exceptions

ArgumentException

An expression is not a property access.

Deny<T>(params Expression<Func<T, object?>>[])

Refuse these navigations on T.

public static void Deny<T>(params Expression<Func<T, object?>>[] navigations)

Parameters

navigations Expression<Func<T, object>>[]

Property expressions, as in o => o.Employee.

Type Parameters

T

The entity type the navigations are declared on.

Exceptions

ArgumentException

An expression is not a property access.

FirstForbiddenHop(Type, string)

The leading part of path that policy refuses, or null if the whole path is permitted.

public static string? FirstForbiddenHop(Type rootType, string path)

Parameters

rootType Type

The entity type the path starts from.

path string

A navigation path, dot- or slash-separated.

Returns

string

The refused leading path, or null.

Remarks

The return value names the hop that was refused rather than the path that was asked for, so a refusal at the first hop does not disclose whether the rest of the path exists. A path that does not resolve against the model returns null: that is Validate(Type)'s to report, not this.

Reset()

Forget every registration, and the resolved rules. Intended for tests.

public static void Reset()

Validate(params Type[])

Resolve these types' rules now, so a contradiction is reported at startup rather than on whichever request first touches it.

public static void Validate(params Type[] entityTypes)

Parameters

entityTypes Type[]

The entity types to resolve.

Exceptions

InvalidOperationException

A type names the same navigation in both an allow and a deny from the same source.