API Management policy expressions

Policy expressions syntax is C# 6.0. Each expression has access to the implicitly provided context variable and an allowed subset of .NET Framework types.

Note

For more information about policy expressions, see the Policy Expressions video.

For demonstrations of configuring policies using policy expressions, see Cloud Cover Episode 177: More API Management Features with Vlad Vinogradsky. This video contains the following policy expression demonstrations.

  • 10:30 - See how to apply policy at the API level to supply context information to the backend service using the Set query string parameter and Set HTTP header policies. At 12:10 there is a demo of calling an operation in the developer portal where you can see these policies at work.
    • 13:50 - See how to use the Validate JWT policy to pre-authorize access to operations based on token claims. Fast forward to 15:00 to see the policies configured in the policy editor and then to 18:50 for a demonstration of calling an operation from the developer portal both with and without the required authorization token.
    • 21:00 - See how to use an API Inspector trace to see how policies are evaluated and the results of the evaluations.
    • 25:25 - See how to use policy expressions with the Get from cache and Store to cache policies to configure API Management response caching duration that matches the response caching of the backend service as specified by the backed service's Cache-Control directive.
    • 34:30 - See how to perform content filtering by removing data elements from the response received from the backend service using the Control flow and Set body policies. Start at 31:50 to see an overview of The Dark Sky Forecast API used for this demo.
    • To download the policy statements used in this video, see the api-management-samples/policies github repo.

Syntax

Single statement expressions are enclosed in @(expression), where expression is a well-formed C# expression statement.

Multi-statement expressions are enclosed in @{expression}. All code paths within multi-statement expressions must end with a return statement.

Examples

@(true)  

@((1+1).ToString())  

@("Hi There".Length)  

@(Regex.Match(context.Response.Headers.GetValueOrDefault("Cache-Control",""), @"max-age=(?<maxAge>\d+)").Groups["maxAge"]?.Value)  

@(context.Variables.ContainsKey("maxAge") ? int.Parse((string)context.Variables["maxAge"]) : 3600)  

@{   
  string value;   
  if (context.Request.Headers.TryGetValue("Authorization", out value))   
  {   
    return Encoding.UTF8.GetString(Convert.FromBase64String(value));  
  }   
  else   
  {   
    return null;  
  }  
}  

Usage

Expressions can be used as attribute values or text values in any of the API Management policies, unless the policy reference specifies otherwise.

Important

Note that when you use policy expressions, there is only limited verification of the policy expressions when the policy is defined. Since the expressions are executed at run-time in the inbound or outbound pipeline by the gateway, any run-time exceptions generated by the policy expressions will result in a runtime error in the API call.

.NET Framework types allowed in policy expressions

The following table lists the .NET Framework types and their members that are allowed in policy expressions.

CLR type Supported methods
Newtonsoft.Json.Linq.Extensions All methods are supported
Newtonsoft.Json.Linq.JArray All methods are supported
Newtonsoft.Json.Linq.JConstructor All methods are supported
Newtonsoft.Json.Linq.JContainer All methods are supported
Newtonsoft.Json.Linq.JObject All methods are supported
Newtonsoft.Json.Linq.JProperty All methods are supported
Newtonsoft.Json.Linq.JRaw All methods are supported
Newtonsoft.Json.Linq.JToken All methods are supported
Newtonsoft.Json.Linq.JTokenType All methods are supported
Newtonsoft.Json.Linq.JValue All methods are supported
System.Collections.Generic.IReadOnlyCollection<T> All
System.Collections.Generic.IReadOnlyDictionary<TKey, TValue> All
System.Collections.Generic.ISet<TKey, TValue> All
System.Collections.Generic.KeyValuePair<TKey, TValue> Key, Value
System.Collections.Generic.List<TKey, TValue> All
System.Collections.Generic.Queue<TKey, TValue> All
System.Collections.Generic.Stack<TKey, TValue> All
System.Convert All
System.DateTime All
System.DateTimeKind Utc
System.DateTimeOffset All
System.Decimal All
System.Double All
System.Guid All
System.IEnumerable<T> All
System.IEnumerator<T> All
System.Int16 All
System.Int32 All
System.Int64 All
System.Linq.Enumerable<T> All methods are supported
System.Math All
System.MidpointRounding All
System.Nullable<T> All
System.Random All
System.SByte All
System.Security.Cryptography. HMACSHA384 All
System.Security.Cryptography. HMACSHA512 All
System.Security.Cryptography.HashAlgorithm All
System.Security.Cryptography.HMAC All
System.Security.Cryptography.HMACMD5 All
System.Security.Cryptography.HMACSHA1 All
System.Security.Cryptography.HMACSHA256 All
System.Security.Cryptography.KeyedHashAlgorithm All
System.Security.Cryptography.MD5 All
System.Security.Cryptography.RNGCryptoServiceProvider All
System.Security.Cryptography.SHA1 All
System.Security.Cryptography.SHA1Managed All
System.Security.Cryptography.SHA256 All
System.Security.Cryptography.SHA256Managed All
System.Security.Cryptography.SHA384 All
System.Security.Cryptography.SHA384Managed All
System.Security.Cryptography.SHA512 All
System.Security.Cryptography.SHA512Managed All
System.Single All
System.String All
System.StringSplitOptions All
System.Text.Encoding All
System.Text.RegularExpressions.Capture Index, Length, Value
System.Text.RegularExpressions.CaptureCollection Count, Item
System.Text.RegularExpressions.Group Captures, Success
System.Text.RegularExpressions.GroupCollection Count, Item
System.Text.RegularExpressions.Match Empty, Groups, Result
System.Text.RegularExpressions.Regex .ctor, IsMatch, Match, Matches, Replace
System.Text.RegularExpressions.RegexOptions Compiled, IgnoreCase, IgnorePatternWhitespace, Multiline, None, RightToLeft, Singleline
System.TimeSpan All
System.Tuple All
System.UInt16 All
System.UInt32 All
System.UInt64 All
System.Uri All
System.Xml.Linq.Extensions All methods are supported
System.Xml.Linq.XAttribute All methods are supported
System.Xml.Linq.XCData All methods are supported
System.Xml.Linq.XComment All methods are supported
System.Xml.Linq.XContainer All methods are supported
System.Xml.Linq.XDeclaration All methods are supported
System.Xml.Linq.XDocument All methods are supported
System.Xml.Linq.XDocumentType All methods are supported
System.Xml.Linq.XElement All methods are supported
System.Xml.Linq.XName All methods are supported
System.Xml.Linq.XNamespace All methods are supported
System.Xml.Linq.XNode All methods are supported
System.Xml.Linq.XNodeDocumentOrderComparer All methods are supported
System.Xml.Linq.XNodeEqualityComparer All methods are supported
System.Xml.Linq.XObject All methods are supported
System.Xml.Linq.XProcessingInstruction All methods are supported
System.Xml.Linq.XText All methods are supported
System.Xml.XmlNodeType All

Context variable

A variable named context is implicitly available in every policy expression. Its members provide information pertinent to the \request. All of the context members are read-only.

Context Variable Allowed methods, properties, and parameter values
context Api: IApi

Deployment

LastError

Operation

Product

Request

RequestId: Guid

Response

Subscription

Tracing: bool

User

Variables:IReadOnlyDictionary<string, object>

void Trace(message: string)
context.Api Id: string

Name: string

Path: string

ServiceUrl: IUrl
context.Deployment Region: string

ServiceName: string
context.LastError Source: string

Reason: string

Message: string

Scope: string

Section: string

Path: string

PolicyId: string

For more information about context.LastError, see Error handling.
context.Operation Id: string

Method: string

Name: string

UrlTemplate: string
context.Product Apis: IEnumerable<IApi>

ApprovalRequired: bool

Groups: IEnumerable<IGroup>

Id: string

Name: string

State: enum ProductState {NotPublished, Published}

SubscriptionLimit: int?

SubscriptionRequired: bool
context.Request Body: IMessageBody

Certificate: System.Security.Cryptography.X509Certificates.X509Certificate2

Headers: IReadOnlyDictionary<string, string[]>

IpAddress: string

MatchedParameters: IReadOnlyDictionary<string, string>

Method: string

OriginalUrl:IUrl

Url: IUrl
string context.Request.Headers.GetValueOrDefault(headerName: string, defaultValue: string) headerName: string

defaultValue: string

Returns comma separated request header values or defaultValue if the header is not found.
context.Response Body: IMessageBody

Headers: IReadOnlyDictionary<string, string[]>

StatusCode: int

StatusReason: string
string context.Response.Headers.GetValueOrDefault(headerName: string, defaultValue: string) headerName: string

defaultValue: string

Returns comma separated response header values or defaultValue if the header is not found.
context.Subscription CreatedTime: DateTime

EndDate: DateTime?

Id: string

Key: string

Name: string

PrimaryKey: string

SecondaryKey: string

StartDate: DateTime?
context.User Email: string

FirstName: string

Groups: IEnumerable<IGroup>

Id: string

Identities: IEnumerable<IUserIdentity>

LastName: string

Note: string

RegistrationDate: DateTime
IApi Id: string

Name: string

Path: string

Protocols: IEnumerable<string>

ServiceUrl: IUrl

SubscriptionKeyParameterNames: ISubscriptionKeyParameterNames
IGroup Id: string

Name: string
IMessageBody As<T>(preserveContent: bool = false): Where T: string, JObject, JToken, JArray, XNode, XElement, XDocument

The context.Request.Body.As<T> and context.Response.Body.As<T> methods are used to read a request and response message bodies in a specified type T. By default the method uses the original message body stream and reneders it unavailable after it returns. To avoid that by having the method operate on a copy of the body stream, set the preserveContent parameter to true. Go here to see an example.
IUrl Host: string

Path: string

Port: int

Query: IReadOnlyDictionary<string, string[]>

QueryString: string

Scheme: string
IUserIdentity Id: string

Provider: string
ISubscriptionKeyParameterNames Header: string

Query: string
string IUrl.Query.GetValueOrDefault(queryParameterName: string, defaultValue: string) queryParameterName: string

defaultValue: string

Returns comma separated query parameter values or defaultValue if the parameter is not found.
T context.Variables.GetValueOrDefault<T>(variableName: string, defaultValue: T) variableName: string

defaultValue: T

Returns variable value cast to type T or defaultValue if the variable is not found.

This method throws an exception if the specified type does not match the actual type of the returned variable.
BasicAuthCredentials AsBasic(input: this string) input: string

If the input parameter contains a valid HTTP Basic Authentication authorization request header value, the method returns an object of type BasicAuthCredentials; otherwise the method returns null.
bool TryParseBasic(input: this string, result: out BasicAuthCredentials) input: string

result: out BasicAuthCredentials

If the input parameter contains a valid HTTP Basic Authentication authorization request header value, the method returns true and the result parameter contains a value of type BasicAuthCredentials; otherwise the method returns false.
BasicAuthCredentials Password: string

UserId: string
Jwt AsJwt(input: this string) input: string

If the input parameter contains a valid JWT token value, the method returns an object of type Jwt; otherwise the method returns null.
bool TryParseJwt(input: this string, result: out Jwt) input: string

result: out Jwt

If the input parameter contains a valid JWT token value, the method returns true and the result parameter contains a value of type Jwt; otherwise the method returns false.
Jwt Algorithm: string

Audience: IEnumerable<string>

Claims: IReadOnlyDictionary<string, string[]>

ExpirationTime: DateTime?

Id: string

Issuer: string

NotBefore: DateTime?

Subject: string

Type: string
string Jwt.Claims.GetValueOrDefault(claimName: string, defaultValue: string) claimName: string

defaultValue: string

Returns comma separated claim values or defaultValue if the header is not found.

Next steps

For more information working with policies, see Policies in API Management.