locked
metadata vs field tags RRS feed

  • Question

  • User-2013179010 posted

    I've been using a tonne of metadata, custom attribs and whatnot. It's cool alright, but it's getting to the point where my metadata classes are beginning to look like a presentation markup. This seems very very wrong. It's hard to make quick UI changes when your titles and whatnot aren't declared in the aspx, and I feel generally dirty putting properties that directly relate to the presentation layer in here.

    Beyond the philosophical question of concerns, there's a practical problem and that is that if I ever want to display a model in a form or grid that I don't want configured with all the fields and attendant metadata options, i have to disable autogeneration of fields and write them all out by hand which isn't so bad, but does mean i've just duplicated or lost a good deal of information (think of the ColumnOrderAttribute).

    I guess I wish there was a way that attributes would still apply to columns even if i manually declare a DynamicField for it rather than let the fieldgenerator do the work. That way I could leave purely presentation options (like columnorder) up to the view where they belong, and keep my logical options in the metadata (like showing or hiding fields based on user roles).

    Thursday, September 11, 2008 12:30 PM

Answers

  • User-797310475 posted

    (...) So my column order attributes, visibility attributes, permissions attributes, whatever, the code to deal with them all is in a custom field generator, which never gets involved when I lay out columns manually like

    <Fields> <asp:DynamicField DataField="blah" /> </Fields

    etc. Which is something I frequently want to do, aspx being for "layout" or so I'm told. Basically I'd rather not try and jam all my layout rules into the metadata, and even if i did want to, I have multiple forms per model, and I don't want ALL the same columns in all of them.

    I can see that there's a design issue there - what has precedence in layout rules, explicit aspx tags or metadata? But I don't want to do all my form layout in metadata attributes, so I need a way of applying metadata information without field generators.

    It seems like you are referring here to attributes that affect the behavior of your custom field generator. Because the DynamicField class has not idea about your custom attributes, it can't really act upon them. However, you could write a derived DynamicField class that could be aware of your custom attributes and do things such as setting a field to not be visible when your visibility or permission attributes indicate that it should not. Regarding the column order, there isn't really anything we can do since the order is implied via the way you lay out your fields in markup. The only alternative i can think of is having code in the page that adds the fields, but then it's not that different from the field generator.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, September 11, 2008 6:46 PM

All replies

  • User-330204900 posted

    Have a look at my series on database based permissions which stores the metadata to do with security in a database and then uses Dynamic Data Futures to add them at runtime, and allow them to be edited by admin:

    1. Part 1 - Create the database tables.
    2. Part 2 - Add a User Interface to modify the permissions.
    3. Part 3 - User Marcin's InMemoryMetadataProvider to add the database based permissions to the Metadata at runtime.
    4. Part 4 - Add components from A DynamicData Attribute Based Permission Solution using User Roles to consume the database based metadata.
    5. Part 5 - Oops! Table Names with Spaces in them and Pluralization.

    Hope this helps [:D]

    Thursday, September 11, 2008 12:51 PM
  • User-2013179010 posted

    That looks handy steve but my issue is more general than that. I have metadata all over my models, but if I want to explicitly list fields for a grid of detailview i essentially lose and have to reimplement all that. It seems like a mess unless I set all my controls to AutoGenerate fields, which is not something I want to do because then I'll end up putting tonnes of inappropriate display info into metadata, and could need to make 2 different views of the same model besides.

     If the DynamicField would pay attention to the metadata on columns that'd help.

    Thursday, September 11, 2008 1:46 PM
  • User-330204900 posted

    What metadata is DynamicField not responding to?

    Thursday, September 11, 2008 2:12 PM
  • User-2013179010 posted

    Well I and DDF set up properties based on attributes in field generators right? Only field generators only kick in when you're autogenerating rows / columns. So my column order attributes, visibility attributes, permissions attributes, whatever, the code to deal with them all is in a custom field generator, which never gets involved when I lay out columns manually like

    <Fields> <asp:DynamicField DataField="blah" /> </Fields

    etc. Which is something I frequently want to do, aspx being for "layout" or so I'm told. Basically I'd rather not try and jam all my layout rules into the metadata, and even if i did want to, I have multiple forms per model, and I don't want ALL the same columns in all of them.

    I can see that there's a design issue there - what has precedence in layout rules, explicit aspx tags or metadata? But I don't want to do all my form layout in metadata attributes, so I need a way of applying metadata information without field generators.

    Thursday, September 11, 2008 4:36 PM
  • User-330204900 posted

    I do see what you mean now. maybe the team will come back on this with some wize words [:D]

    Thursday, September 11, 2008 5:00 PM
  • User-797310475 posted

    (...) So my column order attributes, visibility attributes, permissions attributes, whatever, the code to deal with them all is in a custom field generator, which never gets involved when I lay out columns manually like

    <Fields> <asp:DynamicField DataField="blah" /> </Fields

    etc. Which is something I frequently want to do, aspx being for "layout" or so I'm told. Basically I'd rather not try and jam all my layout rules into the metadata, and even if i did want to, I have multiple forms per model, and I don't want ALL the same columns in all of them.

    I can see that there's a design issue there - what has precedence in layout rules, explicit aspx tags or metadata? But I don't want to do all my form layout in metadata attributes, so I need a way of applying metadata information without field generators.

    It seems like you are referring here to attributes that affect the behavior of your custom field generator. Because the DynamicField class has not idea about your custom attributes, it can't really act upon them. However, you could write a derived DynamicField class that could be aware of your custom attributes and do things such as setting a field to not be visible when your visibility or permission attributes indicate that it should not. Regarding the column order, there isn't really anything we can do since the order is implied via the way you lay out your fields in markup. The only alternative i can think of is having code in the page that adds the fields, but then it's not that different from the field generator.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, September 11, 2008 6:46 PM
  • User-330204900 posted

    These may or may not be wise word!

    This is what I thought if you create your own AdvancedDyanmicField which inherits DynamicField and the same for DynamicControl you couold do sonthing like this: 

    public class AdvancedDynamicField : DynamicField
    {
    	public override void InitializeCell(
    		DataControlFieldCell cell,
    		DataControlCellType cellType,
    		DataControlRowState rowState,
    		int rowIndex)
    	{
    		if (cellType == DataControlCellType.DataCell)
    		{
    			var control = new DynamicControl() { DataField = DataField };
    
    			// Copy various properties into the control
    			control.UIHint = UIHint;
    			control.HtmlEncode = HtmlEncode;
    			control.NullDisplayText = NullDisplayText;
    
    			// Do all this to get the columns attributes
    			var c = this.Control;
    			var d = c.FindDataSourceControl();
    			MetaTable mt = d.GetTable();
    			MetaColumn col = mt.GetColumn(this.DataField);
    
    			var readOnly = col.Attributes.OfType<ReadOnlyAttribute>().SingleOrDefault();
    
    			if ((rowState & DataControlRowState.Edit) != 0)
    			{
    				if (readOnly != null && readOnly.IsReadOnly)
    				{
    					control.Mode = DataBoundControlMode.ReadOnly;
    				}
    				else
    				{
    					control.Mode = DataBoundControlMode.Edit;
    				}
    			}
    
    			if ((rowState & DataControlRowState.Insert) != 0)
    			{
    				if (readOnly != null && readOnly.IsReadOnly)
    				{
    					control.Mode = DataBoundControlMode.ReadOnly;
    				}
    				else
    				{
    					control.Mode = DataBoundControlMode.Insert;
    				}
    			}
    
    
    			cell.Controls.Add(control);
    		}
    		else
    		{
    			base.InitializeCell(cell, cellType, rowState, rowIndex);
    		}
    	}
    }

    Which checks to see if the field has a ReadOnly attribute set:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class ReadOnlyAttribute : Attribute
    {
    	public ReadOnlyAttribute(Boolean readOnly)
    	{
    		IsReadOnly = readOnly;
    	}
    
    	public Boolean IsReadOnly { get; set; }
    }
    

    Also you will need to either set the Control in you markup to AdvancedDynamicField or set a Tag Mapping up in the web.config

    <pages>
    	<controls>
    		...
    </controls> <tagMapping> <add tagType="System.Web.DynamicData.DynamicField" mappedTagType="AdvancedDynamicField"/> </tagMapping> </pages>

    What do you think?

    Thursday, September 11, 2008 7:18 PM
  • User-2013179010 posted

     Thanks guys this is wisdom incarnate -- I don't actually need the column order thing at all if I'm laying out fields manually anyway I just used it as a (poorly thought out) example. I had tried to create a custom dynamic field but I didn't see an obvious way of pulling up its related MetaColumn which was where all this frustration started. I'll try again with steve's suggestion since that seems like the best solution to me.

    Thursday, September 11, 2008 7:32 PM
  • User-797310475 posted

    I had tried to create a custom dynamic field but I didn't see an obvious way of pulling up its related MetaColumn which was where all this frustration started.

    I see. We will try to make this scenario easier to implement in future versions. Some improvements I can think of include adding an overridable hook that subclasses can implement to further modify the created DynamicControl, as well as easily expose the associated MetaColumn. Any other thoughts?

    Thursday, September 11, 2008 7:42 PM
  • User-330204900 posted

    Hi Zwitterion, this is just a tidy up of the code to get the MetaColumn.

    // Do all this to get the columns attributes
    MetaTable mataTabel = Control.FindDataSourceControl().GetTable();
    MetaColumn column = mataTabel.GetColumn(this.DataField);

    Hope this helps [:D]

    Thursday, September 11, 2008 7:47 PM
  • User-330204900 posted

    Or this: 

    // Do all this to get the columns attributes
    MetaColumn column = Control.FindDataSourceControl().GetTable().GetColumn(this.DataField);
    
     
    Thursday, September 11, 2008 7:48 PM