Web.config - Add the intellisense

I previously explain how to create a custom configuration section in a web.config. But something miss if we want to do all the job.

If you share the library with your favorites colleagues and the haven't the documentation, it is better to include the magic part : INTELLISENSE.

I will show you how to realize the trick.

First, the schema

First of all, we have to create the XML schema which describe our custom configuration section structure. It is preferable to name the schema like ClassnameOfSectionSchema.xsd. In our case, PartnerConfigSectionSchema.xsd.

  1. Open the previous project in Visual Studio

  2. In the library, add a new XML Schema

  1. Press F7 to edit the xml code of the schema

  2. Copy/Paste the code below and replace the original code in the newly created schema

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="PartnerConfigSectionSchema" targetNamespace="http://tempuri.org/PartnerConfigSectionSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/PartnerConfigSectionSchema.xsd" xmlns:mstns="http://tempuri.org/PartnerConfigSectionSchema.xsd"     xmlns:xs="http://www.w3.org/2001/XMLSchema">     
    <xs:complexType name="partnerConfig_T">     
        <xs:choice minOccurs="0" maxOccurs="unbounded">       
            <xs:element minOccurs="0" name="partner">
                <xs:complexType>
                    <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:element name="add">
                            <xs:complexType>
                                <xs:attribute name="key" type="xs:string" use="optional"/>
                                <xs:attribute name="value" type="xs:string" use="optional"/>
                                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
                               </xs:complexType>            
                        </xs:element>
                        <xs:element name="remove">
                            <xs:complexType>                 
                                <xs:attribute name="key" type="xs:string" use="optional"/>      
                                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>       
                             </xs:complexType>
                        </xs:element>
                        <xs:element name="clear">
                            <xs:complexType>
                                <!--tag is empty-->                 
                                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>               
                            </xs:complexType>
                        </xs:element>
                    </xs:choice>
                    <xs:attribute name="Name" use="required" type="xs:string">
                        <xs:annotation>               
                            <xs:documentation>The unique name of the partner</xs:documentation>
                        </xs:annotation>
                    </xs:attribute>
                    <xs:attribute name="Enabled" use="optional" default="false">
                        <xs:annotation>
                            <xs:documentation>Set to true to enabled the partner</xs:documentation>
                        </xs:annotation>
                    </xs:attribute>
                    <xs:attribute name="ClientId" use="optional" type="xs:string">
                        <xs:annotation>
                            <xs:documentation>The client ID of the account to use for the partner's service(s)</xs:documentation>
                        </xs:annotation>
                    </xs:attribute>
                    <xs:attribute name="ClientSecret" use="optional" type="xs:string">
                        <xs:annotation>               <xs:documentation>The client secret of the account to use for the partner's service(s)</xs:documentation>
                        </xs:annotation>
                    </xs:attribute>
                    <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
                </xs:complexType>
            </xs:element>
        </xs:choice>
        <xs:attribute name="configSource" type="xs:string" use="optional"/>
        <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
    </xs:complexType>
    <xs:element name="partnerConfig" type="partnerConfig_T"/>
</xs:schema>

Ok sir ! Copy/paste is magic, but can you explain more ?

Yes, I can ! Let me explain each part of the schema to let you understand well the role of each one.

Explanations

Header

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="PartnerConfigSectionSchema" targetNamespace="http://tempuri.org/PartnerConfigSectionSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/PartnerConfigSectionSchema.xsd" xmlns:mstns="http://tempuri.org/PartnerConfigSectionSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">

This part is the header of the schema where you can found the identifier in the property id.

The collection

<xs:complexType name="partnerConfig_T">     
    <xs:choice minOccurs="0" maxOccurs="unbounded">       
        <xs:element minOccurs="0" name="partner">
            <xs:complexType>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="add">
                        <xs:complexType>
                            <xs:attribute name="key" type="xs:string" use="optional"/>
                            <xs:attribute name="value" type="xs:string" use="optional"/>
                            <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
                               </xs:complexType>            
                        </xs:element>
                    <xs:element name="remove">
                        <xs:complexType>                 
                                <xs:attribute name="key" type="xs:string" use="optional"/>      
                                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>       
                             </xs:complexType>
                    </xs:element>
                    <xs:element name="clear">
                        <xs:complexType>
                            <!--tag is empty-->                 
                                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>               
                            </xs:complexType>
                    </xs:element>
                </xs:choice>
                <xs:attribute name="Name" use="required" type="xs:string">
                    <xs:annotation>               
                            <xs:documentation>The unique name of the partner</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="Enabled" use="optional" default="false">
                    <xs:annotation>
                        <xs:documentation>Set to true to enabled the partner</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="ClientId" use="optional" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>The client ID of the account to use for the partner's service(s)</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="ClientSecret" use="optional" type="xs:string">
                    <xs:annotation>               <xs:documentation>The client secret of the account to use for the partner's service(s)</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
            </xs:complexType>
        </xs:element>
    </xs:choice>
    <xs:attribute name="configSource" type="xs:string" use="optional"/>
    <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
</xs:complexType>

The big piece of the schema which detailed the structure of our custom section.


A. Let's start with the condensed view of the section :

<xs:complexType name="partnerConfig_T">     
    <xs:choice minOccurs="0" maxOccurs="unbounded">       
        ...
    </xs:choice>
    <xs:attribute name="configSource" type="xs:string" use="optional"/>
    <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
</xs:complexType>

We retrieve here :

  • xs:choice which details the content of the section

  • An attribute called configSource. It is a native attribute let use an external configuration source file instead writing into the web.config

  • xs:anyAttribute to indicate many other undeclared attribute can exists on the section element.


B. Continue with the content part :

<xs:complexType name="partnerConfig_T">     
    <xs:choice minOccurs="0" maxOccurs="unbounded">       
        <xs:element minOccurs="0" name="partner">
            <xs:complexType>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="add">
                        <xs:complexType>
                            <xs:attribute name="key" type="xs:string" use="optional"/>
                            <xs:attribute name="value" type="xs:string" use="optional"/>
                            <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
                               </xs:complexType>            
                        </xs:element>
                    <xs:element name="remove">
                        <xs:complexType>                 
                                <xs:attribute name="key" type="xs:string" use="optional"/>      
                                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>       
                             </xs:complexType>
                    </xs:element>
                    <xs:element name="clear">
                        <xs:complexType>
                            <!--tag is empty-->                 
                                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>               
                            </xs:complexType>
                    </xs:element>
                </xs:choice>
                <xs:attribute name="Name" use="required" type="xs:string">
                    <xs:annotation>               
                            <xs:documentation>The unique name of the partner</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="Enabled" use="optional" default="false">
                    <xs:annotation>
                        <xs:documentation>Set to true to enabled the partner</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="ClientId" use="optional" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>The client ID of the account to use for the partner's service(s)</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="ClientSecret" use="optional" type="xs:string">
                    <xs:annotation>               <xs:documentation>The client secret of the account to use for the partner's service(s)</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
            </xs:complexType>
        </xs:element>
    </xs:choice>
    ...
</xs:complexType>

We retrieve here an element partner which is defined by a complex type

<xs:complexType name="partnerConfig_T">     
    <xs:choice minOccurs="0" maxOccurs="unbounded">       
        <xs:element minOccurs="0" name="partner">
            <xs:complexType>
                ...
            </xs:complexType>
        </xs:element>
    </xs:choice>
    ...
</xs:complexType>

The complex contains multiple parts I will detailed below :

  1. The collection verbs to manipulate parameters :

    • add: To add a new element

    • remove: To remove a new element

    • clean: To remove all the element

  2. The attributes you can retrieve on the partner element :

    • Name: The name of the partner, marked as required

    • Enabled: The flag indicating if the partner element is enabled or not

    • ClientId: The client identifier for the partner API

    • ClientSecret: The client secret for the partner API

Usage

Now we have the schema defined. I will show you how to use it to add intellisense in the web.config.

  1. Open the ASP.Net WebForms website with Visual Studio

  2. Open the web.config file

  3. On the Properties panel, expand the property Schemas by clicking on the ...

  1. Click on Add and retrieve your .xsd file to add it in the list

  2. Now you have the intellisense for the partner section directly when you type.

Now, no excuse to help your colleagues, go for it 😎.

Resources

Please find the project illustrating this article on my Github, here.


Let's Connect!

Hi, I'm Yoann. I work as a full-stack developer, solution architect.

If you enjoyed this article, you might enjoy my other content, too.

Github:yblossier

LinkedIn:/in/yoannblossier

Buy Me A Coffee:A special thank you for your support🍵

Thank you for joining me today.

Yoann