Will it be possible or is it already possible to extend the metadata

Last post 05-12-2008 10:08 AM by sjnaughton. 32 replies.

Sort Posts:

  • Will it be possible or is it already possible to extend the metadata

    05-07-2008, 2:55 PM
    • Loading...
    • sjnaughton
    • Joined on 04-29-2008, 1:11 PM
    • Newton-le-Willows, UK
    • Posts 329

    you could use the technique from this post Removing Columns From Gridview in List.aspx Page to filter columns by your own attributes.

    Steve

    Seeking the elegant solution.
    [Oh! If olny I colud tpye!Confused]
    c# Bits blog
  • Re: Will it be possible or is it already possible to extend the metadata

    05-07-2008, 6:30 PM
    Answer
    • Loading...
    • davidebb
    • Joined on 06-11-2002, 8:31 AM
    • Redmond, WA
    • Posts 859
    • AspNetTeam

    Hi Steve,

    I'm not sure I quite understand what you're asking.  It is possible to create new metadata attributes that your custom code can look for and act upon.  But maybe that's not what you meant?

    thanks,
    David

  • Re: Will it be possible or is it already possible to extend the metadata

    05-07-2008, 6:38 PM
    • Loading...
    • sjnaughton
    • Joined on 04-29-2008, 1:11 PM
    • Newton-le-Willows, UK
    • Posts 329

    Yes thats what I meant. Then when you use

    GridView1.ColumnsGenerator = new FilterDataSource(table);

    as described in another post you could deal with things like:

    Read/Write for Admin role
    Read Only for User role
    Hidden for another role

    keeping the logic and the model seperate.

     

    Steve

    Seeking the elegant solution.
    [Oh! If olny I colud tpye!Confused]
    c# Bits blog
  • Re: Will it be possible or is it already possible to extend the metadata

    05-07-2008, 6:49 PM
    • Loading...
    • davidebb
    • Joined on 06-11-2002, 8:31 AM
    • Redmond, WA
    • Posts 859
    • AspNetTeam

    Yes, you absolutely could do this.  At some point, we had considered creating such security related attributes ourselves, but concluded that we could not come up with something that would please everyone.  But the system works in a way that you are encouraged to create your own custom attributes that fit your scenario.  In your generator, you can call MetaColumn.GetAttributes to get all the attributes for the column.

    David

  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 3:15 AM
    • Loading...
    • sjnaughton
    • Joined on 04-29-2008, 1:11 PM
    • Newton-le-Willows, UK
    • Posts 329

    So all I need to do is create my own metadata class add the attribute to the Metadata class and then call MetaColumn.GetAttributes and it will return a collection of the attributes?

    Steve

    Seeking the elegant solution.
    [Oh! If olny I colud tpye!Confused]
    c# Bits blog
  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 5:24 AM
    • Loading...
    • sjnaughton
    • Joined on 04-29-2008, 1:11 PM
    • Newton-le-Willows, UK
    • Posts 329

    Hi David I've tried that here is my Attribute class:

    using System;
    
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true)]
    public class PermissionsAttribute : System.Attribute
    {
        public PermissionsAttribute(Permissions permission, String role)
        {
            this._permission = permission;
            this._role = role;
        }
    
        private String _role;
        public String Role
        {
            get { return this._role; }
            set { this._role = value; }
        }
    
        private Permissions _permission;
        public Permissions Permission
        {
            get { return this._permission; }
            set { this._permission = value; }
        }
    
        public enum Permissions
        {
            ReadWrite,
            ReadOnly,
            Hidden
        }
    }
    Here is My Metadata class
     
    using System;
    using System.ComponentModel.DataAnnotations;
    //using NotAClue;
    
    [MetadataType(typeof(OrderMetadata))]
    public partial class Order
    {
    }
    
    [Permissions(PermissionsAttribute.Permissions.ReadOnly, "User")]
    [Permissions(PermissionsAttribute.Permissions.ReadWrite, "Admin")]
    public class OrderMetadata
    {
        [Permissions(PermissionsAttribute.Permissions.Hidden, "*")]
        [Permissions(PermissionsAttribute.Permissions.ReadWrite, "Admin")]
        public Object OrderDate { get; set; }
    }
     
    The problem I'm having is that if I include two attibute on the class (see above) I get the error below: 

    The main type 'Order' already contains at least one attribute of type 'PermissionsAttribute'.

    And if I have two attributes on the property (see above) only the first on shows in the collection.

    Steve

    Seeking the elegant solution.
    [Oh! If olny I colud tpye!Confused]
    c# Bits blog
  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 8:08 AM
    • Loading...
    • tlanier
    • Joined on 04-29-2008, 1:20 PM
    • Posts 67

    Steve,

    This is a great idea!  Much better than what I was planning to do.

    Tommy

  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 8:16 AM
    • Loading...
    • tlanier
    • Joined on 04-29-2008, 1:20 PM
    • Posts 67

    Maybe you could use an attribute per role.

    [UserPermissions(ReadOnly)]

    [AdminPermissions(ReadWrite)]

    [DefaultPermission(Hidden)]

    public Object OrderDate { get; set; }

    Maybe you would define a default permissions to be set unless otherwise overridden.

    Tommy

     

  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 9:07 AM
    • Loading...
    • sjnaughton
    • Joined on 04-29-2008, 1:11 PM
    • Newton-le-Willows, UK
    • Posts 329

    Hi Tommy that would be a workaround but I wanted somthing a bit more generic that would fit in to any pattern you wanted. Also there may be more groups than just Admin and User level of permissions e.g. Accounts, Sales, Production etc.

    Steve

    Seeking the elegant solution.
    [Oh! If olny I colud tpye!Confused]
    c# Bits blog
  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 11:07 AM
    • Loading...
    • davidebb
    • Joined on 06-11-2002, 8:31 AM
    • Redmond, WA
    • Posts 859
    • AspNetTeam

    DynamicData is going through TypeDescriptor to get the attribute (this allows extensible attribute providers), and unfortunately it does have this restriction that it only supports one attribute of a given type.

    How about reversing Tommy's idea and having one attribute type per permission instead of per role?  e.g. ReadOnlyPermission(), ReadWritePermission().  You can then make those attribute contructors take an arbitrary list of roles (by using 'params object[] roles' as the last argument).

    Then you can write:

    [ReadOnlyPermission("user1", "user2", "user3")]
    [ReadWritePermission("admin1", "admin2")]

    David

  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 12:33 PM
    • Loading...
    • sjnaughton
    • Joined on 04-29-2008, 1:11 PM
    • Newton-le-Willows, UK
    • Posts 329

    Thanks David that sounds like it will do the same.

    Will this restriction always apply of one attribute of a given type?

    Steve

    Seeking the elegant solution.
    [Oh! If olny I colud tpye!Confused]
    c# Bits blog
  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 12:57 PM
    • Loading...
    • sjnaughton
    • Joined on 04-29-2008, 1:11 PM
    • Newton-le-Willows, UK
    • Posts 329

    Here are my finished attributes clsses

    using System;
    
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false)]
    public class ReadWritePermissionAttribute : System.Attribute
    {
        private String[] _roles;
        public ReadWritePermissionAttribute(params String[] roles)
        {
            this._roles = roles;
        }
    }
    
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false)]
    public class ReadOnlyPermissionAttribute : System.Attribute
    {
        private String[] _roles;
        public ReadOnlyPermissionAttribute(params String[] roles)
        {
            this._roles = roles;
        }
    }
    
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false)]
    public class HiddenPermissionAttribute : System.Attribute
    {
        private String[] _roles;
        public HiddenPermissionAttribute(params String[] roles)
        {
            this._roles = roles;
        }
    }

    Some Sample Metadata (Northwind) 

    [MetadataType(typeof(OrderMetadata))]
    public partial class Order
    {
    }
    
    [ReadWritePermission("Admin")]
    [HiddenPermission("Production")]
    public class OrderMetadata
    {
        [ReadWritePermission("Admin")]
        [ReadOnlyPermission("User","Accounts","Sales")]
        public Object OrderDate { get; set; }
    
    }
    And finally I can access the attribute via: 
    _table.Attributes;
    _table.columns[0].column.Attributes;
     
    I could then iterate through the attribute collections returned turing fields or tables on or off etc.
    
    Steve

    Seeking the elegant solution.
    [Oh! If olny I colud tpye!Confused]
    c# Bits blog
  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 1:16 PM
    • Loading...
    • tlanier
    • Joined on 04-29-2008, 1:20 PM
    • Posts 67

    Steve,

    Using your previous example, I'm having trouble detecting the custom attribute. The below code does not work.

    	public ICollection GenerateFields(Control control)
    	{
    		List oFields = new List();
    
    		foreach (MetaColumn col in _table.Columns)
    		{
    			PermissionsAttribute a = 
    				new PermissionsAttribute(PermissionsAttribute.Permissions.ReadOnly, "Admin");
    
    			if (col.Attributes.Contains(a))
    				continue;	// do anything to show it's working
    
    			DynamicField f = new DynamicField();
    
    			f.DataField = col.Name;
    			oFields.Add(f);
    		}
    
    		return oFields;
    	}
    ----------------------------
    In the partial class:
     
    [Permissions(PermissionsAttribute.Permissions.ReadOnly, "Admin")]
    
    public object SerialNo {
    
    get {
    
    return _SerialNo;
    
    }
    
    set {
    
    _SerialNo = value;
    
    }
    
    }
    
    
      
     
    										                
    										                
                									    
  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 1:28 PM
    • Loading...
    • davidebb
    • Joined on 06-11-2002, 8:31 AM
    • Redmond, WA
    • Posts 859
    • AspNetTeam

    Tommy, you can't just call Attribute.Contains(a), as this will look if that exact instance of the attribute is in the collection (which it will never be).  You need to search for Attributes of that type and see if you find the one you care about.  You could write some simple heplers to make this easier.

    David

  • Re: Will it be possible or is it already possible to extend the metadata

    05-08-2008, 2:45 PM
    • Loading...
    • tlanier
    • Joined on 04-29-2008, 1:20 PM
    • Posts 67

    If I do something silly like below, it shows the colum has 4 attributes, none of which are the custom one. I think I'm looking in the wrong place. 

    Attribute: System.SerializableAttribute
    Attribute: System.Runtime.CompilerServices.TypeDependencyAttribute
    Attribute: System.Data.Linq.Mapping.ColumnAttribute
    Attribute: System.Runtime.InteropServices.ComVisibleAttribute

    		foreach (MetaColumn col in _table.Columns)
    		{
    			if (col.Name == "SerialNo")
    			{
    				string</