More SharePoint 2010 Expression Builders
- by Ricardo Peres
Introduction Following my last post, I decided to publish the whole set of expression builders that I use with SharePoint. For all who don’t know about expression builders, they allow us to employ a declarative approach, so that we don’t have to write code for “gluing” things together, like getting a value from the query string, the page’s underlying SPListItem or the current SPContext and assigning it to a control’s property. These expression builders are for some quite common scenarios, I use them quite often, and I hope you find them useful as well. SPContextExpression This expression builder allows us to specify an expression to be processed on the SPContext.Current property object. For example: 1: <asp:Literal runat="server" Text=“<%$ SPContextExpression:Site.RootWeb.Lists[0].Author.LoginName %>”/>
It is identical to having the following code:
1: String authorName = SPContext.Current.Site.RootWeb.Lists[0].Author.LoginName;
SPFarmProperty
Returns a property stored on the farm level:
1: <asp:Literal runat="server" Text="<%$ SPFarmProperty:SomeProperty %>"/>
Identical to:
1: Object someProperty = SPFarm.Local.Properties["SomeProperty"];
SPField
Returns the value of a selected page’s list item field:
1: <asp:Literal runat="server" Text="<%$ SPField:Title %>"/>
Does the same as:
1: String title = SPContext.Current.ListItem["Title"] as String;
SPIsInAudience
Checks if the current user belongs to an audience:
1: <asp:CheckBox runat="server" Checked="<%$ SPIsInAudience:SomeAudience %>"/>
Equivalent to:
1: AudienceManager audienceManager = new AudienceManager(SPServiceContext.Current);
2: Audience audience = audienceManager.Audiences["SomeAudience"];
3: Boolean isMember = audience.IsMember(SPContext.Current.Web.User.LoginName);
SPIsInGroup
Checks if the current user belongs to a group:
1: <asp:CheckBox runat="server" Checked="<%$ SPIsInGroup:SomeGroup %>"/>
The equivalent C# code is:
1: SPContext.Current.Web.CurrentUser.Groups.OfType<SPGroup>().Any(x => String.Equals(x.Name, “SomeGroup”, StringComparison.OrdinalIgnoreCase));
SPProperty
Returns the value of a user profile property for the current user:
1: <asp:Literal runat="server" Text="<%$ SPProperty:LastName %>"/>
Where the same code in C# would be:
1: UserProfileManager upm = new UserProfileManager(SPServiceContext.Current);
2: UserProfile u = upm.GetUserProfile(false);
3: Object property = u["LastName"].Value;
SPQueryString
Returns a value passed on the query string:
1: <asp:GridView runat="server" PageIndex="<%$ SPQueryString:PageIndex %>" />
Is equivalent to (no SharePoint code this time):
1: Int32 pageIndex = Convert.ChangeType(typeof(Int32), HttpContext.Current.Request.QueryString["PageIndex"]);
SPWebProperty
Returns the value of a property stored at the site level:
1: <asp:Literal runat="server" Text="<%$ SPWebProperty:__ImagesListId %>"/>
You can get the same result as:
1: String imagesListId = SPContext.Current.Web.AllProperties["__ImagesListId"] as String;
Code
OK, let’s move to the code. First, a common abstract base class, mainly for inheriting the conversion method:
1: public abstract class SPBaseExpressionBuilder : ExpressionBuilder
2: {
3: #region Protected static methods
4: protected static Object Convert(Object value, PropertyInfo propertyInfo)
5: {
6: if (value != null)
7: {
8: if (propertyInfo.PropertyType.IsAssignableFrom(value.GetType()) == false)
9: {
10: if (propertyInfo.PropertyType.IsEnum == true)
11: {
12: value = Enum.Parse(propertyInfo.PropertyType, value.ToString(), true);
13: }
14: else if (propertyInfo.PropertyType == typeof(String))
15: {
16: value = value.ToString();
17: }
18: else if ((typeof(IConvertible).IsAssignableFrom(propertyInfo.PropertyType) == true) && (typeof(IConvertible).IsAssignableFrom(value.GetType()) == true))
19: {
20: value = System.Convert.ChangeType(value, propertyInfo.PropertyType);
21: }
22: }
23: }
24:
25: return (value);
26: }
27: #endregion
28:
29: #region Public override methods
30: public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
31: {
32: if (String.IsNullOrEmpty(entry.Expression) == true)
33: {
34: return (new CodePrimitiveExpression(String.Empty));
35: }
36: else
37: {
38: return (new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(this.GetType()), "GetValue"), new CodePrimitiveExpression(entry.Expression.Trim()), new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("entry"), "PropertyInfo")));
39: }
40: }
41: #endregion
42:
43: #region Public override properties
44: public override Boolean SupportsEvaluate
45: {
46: get
47: {
48: return (true);
49: }
50: }
51: #endregion
52: }
Next, the code for each expression builder:
1: [ExpressionPrefix("SPContext")]
2: public class SPContextExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String expression, PropertyInfo propertyInfo)
6: {
7: SPContext context = SPContext.Current;
8: Object expressionValue = DataBinder.Eval(context, expression.Trim().Replace('\'', '"'));
9:
10: expressionValue = Convert(expressionValue, propertyInfo);
11:
12: return (expressionValue);
13: }
14:
15: #endregion
16:
17: #region Public override methods
18: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
19: {
20: return (GetValue(entry.Expression, entry.PropertyInfo));
21: }
22: #endregion
23: }
1: [ExpressionPrefix("SPFarmProperty")]
2: public class SPFarmPropertyExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String propertyName, PropertyInfo propertyInfo)
6: {
7: Object propertyValue = SPFarm.Local.Properties[propertyName];
8:
9: propertyValue = Convert(propertyValue, propertyInfo);
10:
11: return (propertyValue);
12: }
13:
14: #endregion
15:
16: #region Public override methods
17: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
18: {
19: return (GetValue(entry.Expression, entry.PropertyInfo));
20: }
21: #endregion
22: }
1: [ExpressionPrefix("SPField")]
2: public class SPFieldExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String fieldName, PropertyInfo propertyInfo)
6: {
7: Object fieldValue = SPContext.Current.ListItem[fieldName];
8:
9: fieldValue = Convert(fieldValue, propertyInfo);
10:
11: return (fieldValue);
12: }
13:
14: #endregion
15:
16: #region Public override methods
17: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
18: {
19: return (GetValue(entry.Expression, entry.PropertyInfo));
20: }
21: #endregion
22: }
1: [ExpressionPrefix("SPIsInAudience")]
2: public class SPIsInAudienceExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String audienceName, PropertyInfo info)
6: {
7: Debugger.Break();
8: audienceName = audienceName.Trim();
9:
10: if ((audienceName.StartsWith("'") == true) && (audienceName.EndsWith("'") == true))
11: {
12: audienceName = audienceName.Substring(1, audienceName.Length - 2);
13: }
14:
15: AudienceManager manager = new AudienceManager();
16: Object value = manager.IsMemberOfAudience(SPControl.GetContextWeb(HttpContext.Current).CurrentUser.LoginName, audienceName);
17:
18: if (info.PropertyType == typeof(String))
19: {
20: value = value.ToString();
21: }
22:
23: return(value);
24: }
25:
26: #endregion
27:
28: #region Public override methods
29: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
30: {
31: return (GetValue(entry.Expression, entry.PropertyInfo));
32: }
33: #endregion
34: }
1: [ExpressionPrefix("SPIsInGroup")]
2: public class SPIsInGroupExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String groupName, PropertyInfo info)
6: {
7: groupName = groupName.Trim();
8:
9: if ((groupName.StartsWith("'") == true) && (groupName.EndsWith("'") == true))
10: {
11: groupName = groupName.Substring(1, groupName.Length - 2);
12: }
13:
14: Object value = SPControl.GetContextWeb(HttpContext.Current).CurrentUser.Groups.OfType<SPGroup>().Any(x => String.Equals(x.Name, groupName, StringComparison.OrdinalIgnoreCase));
15:
16: if (info.PropertyType == typeof(String))
17: {
18: value = value.ToString();
19: }
20:
21: return(value);
22: }
23:
24: #endregion
25:
26: #region Public override methods
27: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
28: {
29: return (GetValue(entry.Expression, entry.PropertyInfo));
30: }
31: #endregion
32: }
1: [ExpressionPrefix("SPProperty")]
2: public class SPPropertyExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String propertyName, System.Reflection.PropertyInfo propertyInfo)
6: {
7: SPServiceContext serviceContext = SPServiceContext.GetContext(HttpContext.Current);
8: UserProfileManager upm = new UserProfileManager(serviceContext);
9: UserProfile up = upm.GetUserProfile(false);
10: Object propertyValue = (up[propertyName] != null) ? up[propertyName].Value : null;
11:
12: propertyValue = Convert(propertyValue, propertyInfo);
13:
14: return (propertyValue);
15: }
16:
17: #endregion
18:
19: #region Public override methods
20: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
21: {
22: return (GetValue(entry.Expression, entry.PropertyInfo));
23: }
24: #endregion
25: }
1: [ExpressionPrefix("SPQueryString")]
2: public class SPQueryStringExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String parameterName, PropertyInfo propertyInfo)
6: {
7: Object parameterValue = HttpContext.Current.Request.QueryString[parameterName];
8:
9: parameterValue = Convert(parameterValue, propertyInfo);
10:
11: return (parameterValue);
12: }
13:
14: #endregion
15:
16: #region Public override methods
17: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
18: {
19: return (GetValue(entry.Expression, entry.PropertyInfo));
20: }
21: #endregion
22: }
1: [ExpressionPrefix("SPWebProperty")]
2: public class SPWebPropertyExpressionBuilder : SPBaseExpressionBuilder
3: {
4: #region Public static methods
5: public static Object GetValue(String propertyName, PropertyInfo propertyInfo)
6: {
7: Object propertyValue = SPContext.Current.Web.AllProperties[propertyName];
8:
9: propertyValue = Convert(propertyValue, propertyInfo);
10:
11: return (propertyValue);
12: }
13:
14: #endregion
15:
16: #region Public override methods
17: public override Object EvaluateExpression(Object target, BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
18: {
19: return (GetValue(entry.Expression, entry.PropertyInfo));
20: }
21: #endregion
22: }
Registration
You probably know how to register them, but here it goes again: add this following snippet to your Web.config file, inside the configuration/system.web/compilation/expressionBuilders section:
1: <add expressionPrefix="SPContext" type="MyNamespace.SPContextExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
2: <add expressionPrefix="SPFarmProperty" type="MyNamespace.SPFarmPropertyExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
3: <add expressionPrefix="SPField" type="MyNamespace.SPFieldExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
4: <add expressionPrefix="SPIsInAudience" type="MyNamespace.SPIsInAudienceExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
5: <add expressionPrefix="SPIsInGroup" type="MyNamespace.SPIsInGroupExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
6: <add expressionPrefix="SPProperty" type="MyNamespace.SPPropertyExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
7: <add expressionPrefix="SPQueryString" type="MyNamespace.SPQueryStringExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
8: <add expressionPrefix="SPWebProperty" type="MyNamespace.SPWebPropertyExpressionBuilder, MyAssembly, Culture=neutral, Version=1.0.0.0, PublicKeyToken=xxx" />
I’ll leave it up to you to figure out the best way to deploy this to your server!