How to build an Expression builder for ASP.Net 2.0

 

When you have read the posts on my blog, you have probably seen the new expression like the <% $ resource … %>, <% $ ConnectionStrings: Name %> etc.

 

If you have not seen them before, then take a look at this post on my blog.

 

You can build your own expression by inherits the ExpressionBuilder class. The ExpressionBuilder class has one method that must be implemented, GetCodeExpression.

 

The GetCodeExpression is used to return the code that will be evaluated during the parsing of the page to return the result of the expression.

 

You can also override the ExpressionBuilder’s EvaluteExpression method if you want your expression builder to be active on no-compile pages. This method most returns the results of the expression. If you implement the EvaluteExpression method, you must also override the SupportsEvaluate property, this property will return a Boolean value, and most return true if the EvaluteExpression method should be used.

 

In the example I’m going to show you, The "My" expression prefix is used:

 

<%$ My:MyExpression %>

 

MyExpression is the expression that is going to be sent to the custom expression builder as the value of the expression.

 

The following code is a very simple custom expression builder that will only return the expression that is specified after the "My" prefix:

 

using System;

using System.CodeDom;

using System.Web.UI;

using System.ComponentModel;

using System.Web.Compilation;

 

public class MyExpressionBuilder : ExpressionBuilder

{

    public MyExpressionBuilder()

    {

    }

 

 

    public static object GetData(string expression, Type targetType, string entryName)

    {

        return expression;

    }

 

 

    public override object EvaluateExpression(object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)

    {

        return MyExpressionBuilder.GetData(entry.Expression, target.GetType(), entry.Name);

    }

 

   

    public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)

    {

        Type type1 = entry.DeclaringType;

        PropertyDescriptor descriptor1 = TypeDescriptor.GetProperties(type1)[entry.PropertyInfo.Name];

        CodeExpression[] expressionArray1 = new CodeExpression[3];

        expressionArray1[0] = new CodePrimitiveExpression(entry.Expression.Trim());

        expressionArray1[1] = new CodeTypeOfExpression(type1);

        expressionArray1[2] = new CodePrimitiveExpression(entry.Name);

        return new CodeCastExpression(descriptor1.PropertyType, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(base.GetType()), "GetData", expressionArray1));

    }

 

 

    public override bool SupportsEvaluate

    {

        get

        {

            return true;

        }

    }

}

 

To use the custom expression builder, you have to register it to the web.config in the <expressionBuilders> section:

 

<configuration>

    <system.web>

       <compilation>

          <expressionBuilders>

              <add expressionPrefix="My" type="MyExpressionBuilder"/>

          </expressionBuilders>

       </compilation>

    </system.web>

</configuration>

 

The ExpressionPrefix attribute of the add element, is the name of the expression prefix:

 

<%$ expressionPrefixName: value %>

 

With the expressionPrefix set to "My", the expression would look like this:

 

<%$ My: value %>

 

The type attribute of the add element, is the type of the custom expression builder you have created. If you have added the custom expression builder to the /Code folder, you only need to write the name of the class. If you have created a separated class library, you have to enter the full name of the class and the assembly where the class exists.

 

Now let’s take a look at the code for MyExpressionBuilder.

 

First you need to add a method that will return the results for your expression, in this example the GetData method will be used to return the results of the expression:

 

public static object GetData(string expression, Type targetType, string entryName)

{

     return expression;

}

 

The code above is used to return the results of the expression argument. In this case it will return the value of the expression. The arguments of the GetData method, will contain the value of the expression, the targetType is the type of where the expression is bounded to, for example a TextBox control etc. The last argument, entryName, is the name of the property where the expression is bounded to. You can for example us the targetType to check if your expression is allowed for the property where the expression is specified.

 

As I mentioned earlier in my post, you can override the ExpressionBuilder’s EvaluteExpression method if you want your expression builder to be active on no-compile pages. The following code overrides the EvaluateExpression method and will call the GetData methoded described above:

 

public override object EvaluateExpression(object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)

    {

        return MyExpressionBuilder.GetData(entry.Expression, target.GetType(), entry.Name);

    }

 

    public override bool SupportsEvaluate

    {

        get

        {

            return true;

        }

    }

 

 

The EvaluteExpression method has four arguments, target, entry, paresedData and context. I will only explain the one used in this example:

 

Target

 

The target arguments have the type of the type where the expression is bounded to.

 

Entry

 

The entry argument holds information about where the expression is bounded, such as the name of the property where the expression is bounded to, and the value of the expression etc.

 

As you can see in the code above, the method will do a call to the GetData method where the expression (value), the type of target and the name of the property where the expression is bound to are passed as arguments. By default the SupportEvalute property will return false, so to use the EvaluteExpression method, the SupportEvaluate property must be override and return true.

 

The next method to override is the GetCodeExpression. This method returns a CodeExpression class. It’s a class with the information about the method that will return the results for the expression, in this case the GetData method:

   

    public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)

    {

        Type type1 = entry.DeclaringType;

        PropertyDescriptor descriptor1 = TypeDescriptor.GetProperties(type1)[entry.PropertyInfo.Name];

        CodeExpression[] expressionArray1 = new CodeExpression[3];

        expressionArray1[0] = new CodePrimitiveExpression(entry.Expression.Trim());

        expressionArray1[1] = new CodeTypeOfExpression(type1);

        expressionArray1[2] = new CodePrimitiveExpression(entry.Name);

        return new CodeCastExpression(descriptor1.PropertyType, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(base.GetType()), "GetData", expressionArray1));

    }

 

The method above will use the CodeCastExpression to specify a CodeExpression (The CodeCastExpression inherits the CodeExpression class). As you can see in the code above, I use the CodeCastExpression to specify the type of the property where the expression is bounded to, and the CodeTypeReferenceExpression to specify which method (GetData) that should be executed to get the results from for the expression. The argument to the GetData method is passed as a CodeExpression array where the items in the array are the value of the arguments that will be passed to the GetData method. I don’t think I need to write more about that, you will probably understand the code, if not, please don’t hesitate to contact me.

 

Here is an example how you can use the custom expression provider:

 

<asp:textbox Id="test" runat="server" Text='<%$ My: Welcome%>'></asp:textbox>

 

When you run this code, the TextBox’s Text property will have the value set to "Welcome".

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值