views:

2061

answers:

2

I am attempting to allow my web designers to use the metadata we have about database fields in the asp.net pages they are creating. The most obvious one is as follows:

<asp:TextBox runat="server" id="txTextBox" MaxLength="<Value From Metadata here>" ... />

All the required metadata is stored in our class objects and is accessible due to its public static nature.

The benefit of this would be that they can set values which

a) might change without them being aware or caring
b) improve the user experience with very little coding effort

and all without having them need worry about what the value is or where it has come from. This will primarily be used for automatically bound controls - i.e. ones which are added with little or no developer interaction.

This question is very similar to One of my previous questions which now works wonderfully (but that was in WPF / XAML ).

The main point of this question is that I want as little developer requirement on this as possible - Ideally there would be some <%# Constant.Value %> type syntax which could be used directly within the Maxlength="" attribute of the asp:Textbox control meaning that no code needs to be added to a page/usercontrol at all.

I have a feeling it isn't possible, but I would love someone to prove me wrong.

Ta

A: 

I think you should be able to do it with something like this

<asp:TextBox runat="server" id="txTextBox" MaxLength="<%=Constants.SomeValue%>" />

But my only concern is that this doesn't really make much sense. If the constant is stored in a .cs file in order to make a change that would cause the new constant value to be reflected in the UI you would have to recompile the site. I think it may be easier just to have a hard coded value in the .aspx page that can be changed easily without the need to recompile the entire codebase. Maybe I'm not understanding the problem though.

Marcus King
<%= %> will not work in properties for server tags. You'll get a compile error.
Ady
The idea is that the site may/may not be recompiled behind the scenes many times, often due to database schema changes. I want the UI (i.e. the HTML in this instance) to reflect the code behind values without having to hard code anything.
Ash
+1  A: 

You can use a data binding expression:

<asp:TextBox MaxLength="<%# Constant.Value %>" />

but, that requires it to be in a databound control. If it's not in a repeater or somesuch, you'll need to call Container.DataBind() at some point in the page lifecycle.

Alternatively, you could create an ExpressionBuilder which would allow syntax such as:

<asp:TextBox MaxLength="<%$ Constants:Value %>" />

Here's a sample that'll pull from a single static dictionary:

using System;
using System.Web.UI;
using System.Web.Compilation;
using System.CodeDom;
using System.Collections.Generic;

class ConstantsExpressionBuilder : ExpressionBuilder {
   private static readonly Dictionary<string, object> Values = 
      new Dictionary<string, object>() {
         { "Value1", 12 },
         { "Value2", false },
         { "Value3", "this is a test" }
      };

   public override bool SupportsEvaluate { get { return true; } }

   public override object EvaluateExpression(object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) {
      string key = entry.Expression.Trim();
      return GetValue(key);
   }

   public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) {
      CodePrimitiveExpression keyExpression = new CodePrimitiveExpression(entry.Expression.Trim());
      return new CodeMethodInvokeExpression(this.GetType(), "GetValue", new CodeExpression[] { keyExpression });       
   }

   public static object GetValue(string key) {
      return Values[key];
   }
}

You'd register this in web.config:

<system.web>
   <compilation>
      <expressionBuilders>
    <add expressionPrefix="Constants" type="ConstantsExpressionBuilder" />
      </expressionBuilders>
   </compilation>
</system.web>

And call it in an ASPX page:

<asp:Textbox runat="server" MaxLength="<%$ Constants:Value1 %>" ReadOnly="<%$ Constants:Value2 %>" Text="<%$ Constants:Value3 %>" />

Which should produce:

<input type="text" maxlength="12" readonly="false" value="this is a test" />

in the HTML output.

Mark Brackett
Wow, I had never heard of ExpressionBuilders before. These sound like they could be incredibly handy.
Ady