ASP.Net 4 Web.Config Changes

by Heathesh 5. May 2010 06:23

UPDATE: Before using web.config transforms as indicated in point 2 below, please view this known issue: Web.config transform writes extra line break/spaces to values elements under applicationSettings section

With the release of .Net 4 and ASP.Net 4.0 there have been two major changes to the web.config that I really like. I personally think these changes address two very useful features that all developers should know about:

1. The file has been refactored

The web.config has now been refactored, and with ASP.Net 4 a lot of the settings that were previously found in the web.config file have now been moved to the machine.config file. This significantly reduces the size of the file, which I think is a great bonus.

With this change, your web.config file can be EMPTY or alternatively simply contain just the following section:

    <?xml version="1.0"?>
        <configuration>
            <system.web>
                <compilation targetFramework="4.0" />
            </system.web>
        </configuration>


2. Web.config transformations

Web.config transformations cater for moving your application between your relevant environments (e.g. Development, QA, Production). The transformations work on the relevant configurations you setup.

To create your own Configuration build with configuration transformations, create a new ASP.Net Web Application in Visual Studio 2010. Next, in the menu select "Build" and then "Configuration Manager". In the "Active Solution Configuration" drop down, select "New". Name the relevant configuration, for example I'm calling mine "Development" and copying the settings from the "Debug" configuration.

Make sure "Create new project configurations" is selected. Once you click okay, you will see your Web.config file now has a "+" next to it in your solution explorer.

If you don't see the "+", build you solution, right click the web.config file and select "Add Config Transformations".

You will see for each of your build configurations there will be a "Web.[Build Configuration Name].config" file. If you open any of these files, you will see place holders for different sections of your original web.config file.

To change settings per your relevant build configuration, check out the following MSDN Article: Web.config Transformation Syntax for Web Application Project Deployment

Happy deploying!

Tags: , , , , ,

Development | .Net | Visual Studio 2010 | VS2010

Dynamic Data: Prevent inserting and deleting for a specific table

by Heathesh 7. February 2010 04:04

I was using a Dynamic Data Entities Web Application, and my requirement was to have a specific setup table that would only ever have one prepopulated row. This meant that the user should never be allowed to insert a new record, or delete the current record from the table. They should only ever be allowed to edit the record.

To accomplish this, I started off creating a custom attribute that I was going to apply to the specific table's scaffolding. The primary use of scaffolding in Dynamic Data is to hide and display specific fields and tables as required. So to begin with, I personally always create a class to be used for scaffolding for every table within my Dynamic Data site. For example, the table I was currently working with is called SiteSetup, and the scaffolding class I created looked like so:

    using System.ComponentModel.DataAnnotations; //add this using for the MetadataType attribute

    //The namespace used here must be the same as your Entity Model namespace. The best way (if you
    //don't already know the namespace) to find out the correct namespace is to expand your .edmx file
    //and then open the Designer.cs file and you will see the namespace there
    namespace Heathesh.Com.Entity
    {
        /// <summary>
        /// Partial class of my MetaTable, using the MetadataType attribute to indicate the
        /// class I'm using to save my scaffolding info
        /// </summary>
        [MetadataType(typeof(SiteSetupMetaData))]
        public partial class SiteSetup
        {

        }

        public class SiteSetupMetaData
        {
            /// <summary>
            /// I don't want the user to see the Id field, because in this case
            /// the Id field is an int with an Indentity, so the user will never
            /// need to insert or change this
            /// </summary>
            [ScaffoldColumn(false)]
            public object Id { get; set; }
        }
    }


Pay attention to the comments above, especially regarding the namespace. Now I had to create an attribute to indicate that I specifically didn't want to allow insert or delete for this table, so I created my attribute like so:

    using System;

    namespace Heathesh.Com.Entity.Attributes
    {
        /// <summary>
        /// Custom behaviour attribute to be used on MetaTables to prevent inserts and deletes where
        /// required
        /// </summary>
        [AttributeUsage(AttributeTargets.Class)]
        public class CustomBehaviour : System.Attribute
        {
            #region Public Properties
            /// <summary>
            /// Gets or sets a bool indicating whether or not to allow inserts
            /// </summary>
            public bool AllowInsert
            {
                get;
                set;
            }

            /// <summary>
            /// Gets or sets a bool indicating whether or not to allow deletes
            /// </summary>
            public bool AllowDelete
            {
                get;
                set;
            }
            #endregion

            #region Constructor
            /// <summary>
            /// Default constructor forcing the user to indicate whether to allow inserts and deletes
            /// </summary>
            /// <param name="allowInsert"></param>
            public CustomBehaviour(bool allowInsert, bool allowDelete)
            {
                AllowInsert = allowInsert;
                AllowDelete = allowDelete;
            }
            #endregion
        }
    }


The attribute class should be pretty self explanatory. The next thing was I wanted to created a method for my attribute that would allow me to check if the attribute existed on a specific meta table and return the attribute if it did. I also wanted it to be generic, so I created an Attribute Manager class with the relevant code to return any attribute from an attribute collection, like this:

    using System;
    using System.ComponentModel;

    namespace Heathesh.Com.BusinessLogic
    {
        /// <summary>
        /// Attribute manager to read custom attributes on classes, I made this static
        /// so I could use it as an Extension method
        /// </summary>
        public static class AttributeManager
        {
            /// <summary>
            /// Gets the specified attribute from the attribute collection
            /// </summary>
            /// <param name="attributes">Extends an Attribute collection</param>
            /// <param name="attributeType">The type of attribute to check for and return if found</param>
            /// <returns></returns>
            public static Attribute GetAttribute(this AttributeCollection attributes, Type attributeType)
            {
                foreach (Attribute attribute in attributes)
                    if (attribute.GetType().Equals(attributeType))
                        return attribute;

                return null;
            }
        }
    }


I used an Extension method so I could simply extend the Attribute collection, and easily have my method available to me on any Attribute collection. So now that I have my attribute, and a manager class to return it, I needed to add my attribute to my scaffolding code to indicate that I wanted to disable insert and delete for my SiteSetup table. So I changed my SiteSetup scaffolding code to look like this:

    using System.ComponentModel.DataAnnotations; //add this using for the MetadataType attribute
    using Heathesh.Com.Entity.Attributes; //* USING TO ALLOW ME TO ACCESS MY ATTRIBUTE *

    //The namespace used here must be the same as your Entity Model namespace. The best way (if you
    //don't already know the namespace) to find out the correct namespace is to expand your .edmx file
    //and then open the Designer.cs file and you will see the namespace there
    namespace Heathesh.Com.Entity
    {
        /// <summary>
        /// Partial class of my MetaTable, using the MetadataType attribute to indicate the
        /// class I'm using to save my scaffolding info
        /// </summary>
        [MetadataType(typeof(SiteSetupMetaData))]
        [CustomBehaviour(false, false)] //* NEW ATTRIBUTE *
        public partial class SiteSetup
        {

        }

        public class SiteSetupMetaData
        {
            /// <summary>
            /// I don't want the user to see the Id field, because in this case
            /// the Id field is an int with an Indentity, so the user will never
            /// need to insert or change this
            /// </summary>
            [ScaffoldColumn(false)]
            public object Id { get; set; }
        }
    }



Looking at the code, you'll see I added the new using for the attribute, and the attribute above the "public partial class SiteSetup". Okay,  now the last thing left was to remove the insert and delete buttons on the List and Details pages of my Dynamic Data site if  the attribute was present and set appropriately. To begin with, I found my List page (DynamicData\PageTemplates\List.aspx) and opened the code behind. First to hide the insert, I added the following code at the bottom of my Page_Load:

    Attribute customBehaviour = table.Attributes.GetAttribute(typeof(CustomBehaviour));

    if (customBehaviour != null)
        InsertHyperLink.Visible = ((CustomBehaviour)customBehaviour).AllowInsert;


Next, I open my List.aspx file and added an event to the OnDataBound like so: OnDataBound="GridView1_DataBound". I then created the method in my code behind as well as a method to hide the button if required like so:

    /// <summary>
    /// Handles the grid view data bound event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void GridView1_DataBound(object sender, EventArgs e)
    {
        Attribute customBehaviour = table.Attributes.GetAttribute(typeof(CustomBehaviour));

        if (customBehaviour != null)
            hideDeleteColumn(((CustomBehaviour)customBehaviour).AllowDelete);
    }

    /// <summary>
    /// Hides the delete column
    /// </summary>
    /// <param name="hide"></param>
    private void hideDeleteColumn(bool show)
    {
        if (!show)
            foreach (GridViewRow gridViewRow in GridView1.Rows)
                ((LinkButton)gridViewRow.Cells[0].Controls[3]).Visible = false;
    }

That took care of my List.aspx page, I next opened my Details.aspx page (DynamicData\PageTemplates\Details.aspx) and added an OnLoad event to my DetailsView1 like so: OnLoad="DetailsView1_Load". I then added the relevant code for the OnLoad method in my code behind like so:

    /// <summary>
    /// Handles the details view load
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void DetailsView1_Load(object sender, EventArgs e)
    {
        Attribute customBehaviour = table.Attributes.GetAttribute(typeof(CustomBehaviour));

        if (customBehaviour != null)
            DetailsView1.FindControl("DeleteLinkButton").Visible = ((CustomBehaviour)customBehaviour).AllowDelete;
    }


That was it, I compiled and ran the application, and insert and delete were available for all my tables except the SiteSetup table as I required.

Happy coding!



Powered by BlogEngine.NET 1.5.0.7 (with enhancements by Heathesh)
Theme by Mads Kristensen (with tweeks by Heathesh)

Certifications

Microsoft Certified Professional

Microsoft Certified Technology Specialist

Answer Questions

 

Tag cloud

Calendar

<<  July 2014  >>
MoTuWeThFrSaSu
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

View posts in large calendar

http://heathesh.com