C# .NET - Application Settings Storage

Asked By Jamie Gates
13-Mar-10 05:22 AM

I am creating a small C# “helper” application and being one of my first, I am looking for direction in storing configuration information.

This “helper” application allows the user to switch between environments of another application, either “production” or “test”. This other application contains databases in file shares that are dependent on the department of the organization he/she is in. Ideally, the user would select the department, and test and production database locations would be modified relative to that department. Currently, there are 3 departments that utilize the application, but there can always be more in the future.

I was originally going to store the department and database location information in the application settings (app.config, or user.config). The user should not be able modify the values, but an administrator should. That is OK, as I planned to store the information using application scope. Changing these settings could be done in the app.config file manually, or an “admin” tool created to make the changes, which is perfectly OK, since by best practices, these settings should not be changed within the program. Beginning to program the dynamic settings and storage portions has now caused an issue I am stumped on (I originally was using static variables).

 

I can setup the 3 departments and database locations in the settings tool manually, but what happens if an admin needs to add or remove a department? An admin would not be able to add the department to the app.config file and it be available to the user in the program. Also, and what made me first identify this issue, how do I iterate though the settings file to populate my combobox for the user to select the department?

The app.config file would look something like this:

01.<appSettings file="">
02.        <clear />
03.        <add key="department1" value="Department 1" />
04.        <add key="department1DbProductionLocation" value="\\dept1\fileshare" />
05.        <add key="department1DbTestLocation" value="\\dept1\TestFileshare" />
06.        <add key="department2" value="Department 2" />
07.        <add key="department2DbProductionLocation" value="\\dept2\fileshare" />
08.        <add key="department2DbTestLocation" value="\\dept2\TestFileshare" />
09.        <add key="department3" value="Department 3" />
10.        <add key="department3DbProductionLocation" value="\\dept3\fileshare" />
11.        <add key="department3DbTestLocation" value="\\dept3\TestFileshare" />
12.</appSettings>

I was playing with some code and was able to add values to keys (delimited by commas) which would look something like this:

1.<appSettings file="">
2.        <clear />
3.        <add key="departmentName" value="Department1,Department2,Department3" />
4.        <add key="departmentDbProductionLocation" value="\\dept1\fileshare,\\dept2\fileshare,\\dept3\fileshare" />
5.        <add key="departmentDbTestLocation" value="\\dept1\TestFileshare,\\dept2\TestFileshare,\\dept3\TestFileshare"  />
6.</appSettings>

I don’t really prefer this—it doesn’t seem as structured as I would like, and I didn’t want to develop on it further without ruling-out all other options. Also, I can see adding/removing departments will require more attention for the admin.

Another option I had come across is using serialization. I already have a Department class storing these values in instance variables. I have reviewed some documentation on serializing the class, but unsure if this is the best method to go about storing the application settings. From what I can tell, a serialized file will store one objects data in the XML file—is this correct? Where would other object information be stored? I imagine I would have 3 Department objects defined at any time. I do like how this is structured, though. A drawback is that it does not use the app.config file, but rather, a completely separate file, correct?

I’m mainly looking for direction on how to best store this information:

1.       App.config settings file, and I am missing something fundamental to it in order to accomplish what I would like?

2.       App.config settings file by adding multiple values to the generic key?

3.       Serialize my Department class?

4.       Create custom XML file/definition? I have little to no XML knowledge so can be challenging.

5.       Some other method

This helper app is more to learn C# and programming techniques in a real-world application as well as learning other technologies, like XML if needed. I always seem to get stuck when applying best or common practices. Any help would be greatly appreciated. Thanks.

Custom Configuration Sections  Custom Configuration Sections

15-Mar-10 07:08 AM
Hi,

Sounds like you want to make use of Custom Configuration Sections.  You can then encrypt these as you would any other section and provide an administration tool to edit the values (which would also conveniently decrypt and encrypt the configuration):

Custom Configuration Sections:
http://msdn.microsoft.com/en-us/library/2tw134k3.aspx
http://www.codeproject.com/KB/cs/CustomConfigurationSectio.aspx

Encrypting Configuration Sections:
http://www.davidhayden.com/blog/dave/archive/2005/11/17/2572.aspx

HTH,

Adam
  Jamie Gates replied to Adam Houldsworth
15-Mar-10 02:48 PM

Thanks Adam. When researching, I do remember coming across Custom Configuration Sections and thought they might be useful, but forgot about them. I have quickly reviewed the posts you mention and it does look more complex than I had hoped, but then again, what fun would it be without a challenge.

Again this was a quick review of the Code Project example, but it appears there is only the distinction between "prod" (production) and "test"--is there a capability to break them into groups/objects by department? The configuration would have multiple departments, each of which has "prod" and "test".

Thanks for your help.

Sample Code  Sample Code

15-Mar-10 04:32 PM
Hi Jamie,

You would do something like the following (excuse the code dump).

Given the following XML:

<myCustomSection>
    <departments>
        <department name="dept1" type="production">
            <items>
                <clear />
                <item name="foo" value="bar" />
                <item name="foo2" value="bar2" />
            </items>
        </department>
        <department name="dept2" type="test">
            <items>
                <clear />
                <item name="foo" value="bar" />
                <item name="foo2" value="bar2" />
            </items>
        </department>
    </departments>
</myCustomSection>

You would use the following code to describe it:

public class MyCustomSection : ConfigurationSection
{
    [ConfigurationProperty("departments")]
    [ConfigurationCollection(typeof(DepartmentElementCollection), AddItemName = "department")]
    public DepartmentElementCollection Departments
    {
        get
        {
            return (this["departments"] ?? new DepartmentElementCollection())
                as DepartmentElementCollection;
        }
    }
}
 
public class DepartmentElementCollection : ConfigurationElementCollection
{
    public DepartmentElement this[int index]
    {
        get { return base.BaseGet(index) as DepartmentElement; }
        set
        {
            if (base.BaseGet(index) != null)
                base.BaseRemoveAt(index);
 
            this.BaseAdd(index, value);
        }
    }
 
    protected override ConfigurationElement CreateNewElement()
    {
        return new DepartmentElement();
    }
 
    protected override object GetElementKey(ConfigurationElement element)
    {
        return (element as DepartmentElement).Name;
    }
}
 
public class DepartmentElement : ConfigurationElement
{
    [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
    public string Name
    {
        get { return this["name"] as string; }
        set { this["name"] = value; }
    }
 
    [ConfigurationProperty("type", IsRequired = true)]
    public string Type
    {
        get { return this["type"] as string; }
        set { this["type"] = value; }
    }
 
    [ConfigurationProperty("items")]
    [ConfigurationCollection(typeof(ItemElementCollection), AddItemName = "item")]
    public ItemElementCollection Items
    {
        get
        {
            return (this["items"] ?? new ItemElementCollection())
                as ItemElementCollection;
        }
    }
}
 
public class ItemElementCollection : ConfigurationElementCollection
{
    public ItemElement this[int index]
    {
        get { return base.BaseGet(index) as ItemElement; }
        set
        {
            if (base.BaseGet(index) != null)
                base.BaseRemoveAt(index);
 
            this.BaseAdd(index, value);
        }
    }
 
    protected override ConfigurationElement CreateNewElement()
    {
        return new ItemElement();
    }
 
    protected override object GetElementKey(ConfigurationElement element)
    {
        return (element as ItemElement).Name;
    }
}
 
public class ItemElement : ConfigurationElement
{
    [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
    public string Name
    {
        get { return this["name"] as string; }
        set { this["name"] = value; }
    }
 
    [ConfigurationProperty("value", IsRequired = true)]
    public string Value
    {
        get { return this["value"] as string; }
        set { this["value"] = value; }
    }
}

Its not entirely complete, you need to add your custom section to the <configSections> section.

HTH,

Adam
  Jamie Gates replied to Adam Houldsworth
21-Mar-10 05:14 AM

Wow, thanks a lot Adam. I have been very busy with work, so I have not had much time to look into this the past week, but after reviewing your info and reading-up on custom configurations, I think I'm understanding it. Most info I have read seems really simplified, likely due to them not creating elements and collections.

It seems the first thing to do is identify the structure of the XML. What you provided doesn't quite meet what I was thinking, but slightly adjusted:

01.<myCustomSection>
02.      <departments>
03.        <department name="County Counsel" abbreviation="CC">
04.          <dbLocations>
05.            <clear />
06.            <dbLocation name="production" value="\\CC\fileshare\" />
07.            <dbLocation name="test" value="\\CC\TestFileshare\" />
08.          </dbLocations>
09.        </department>
10.        <department name="District Attorney" abbreviation="DA">
11.          <dbLocations>
12.            <clear />
13.            <dbLocation name="production" value="\\DA\fileshare\" />
14.            <dbLocation name="test" value="\\DA\TestFileshare\" />
15.          </dbLocations>
16.        </department>
17.        <department name="Public Defender" abbreviation="PD">
18.          <dbLocations>
19.            <clear />
20.            <dbLocation name="production" value="\\PD\fileshare\" />
21.            <dbLocation name="test" value="\\PD\TestFileshare\" />
22.          </dbLocations>
23.        </department>
24.      </departments>
25.    </myCustomSection>
 

I have also adjusted the code in the custom configuration class. When compiling, I am getting messages stating "Could not find schema information for the element departments'". This is for all elements and attributes in the custom config section. Do i need to/should define a schema definition for the custom config section?

 
  Adam Houldsworth replied to Jamie Gates
21-Mar-10 07:51 AM
Have you specified your main section handler in the configuration file's <configSections> part?

Adam
  Jamie Gates replied to Adam Houldsworth
21-Mar-10 02:32 PM

I'd say the type attribute in the configuration file's <configSections> part has been confusing.

From example code, I placed this, but was not really sure what the type was:

1.<?xml version="1.0" encoding="utf-8"?>
2.<configuration>    
3.    <configSections>
4.        ...
5.        <section name="myCustomSection" type="Fully.Qualified.TypeName.DeptConfigurations,AssemblyName" />
6.    </configSections>
7....
8.</configuration>

I'm sure it shouldn't be "Fully.Qualified.TypeName" but unsure how to define it. After looking at some more info, I have tried placing my custom configuration in a namespace:

01.using System;
02.using System.Configuration;
03.  
04.namespace MyApp.Configuration
05.{
06.  
07.    // my original classes
08.    public class DeptConfigurations : ConfigurationSection
    10.     { 
11.        ...
12.    }
13.  
14....
15.  
16.}

and changing the section handler to

1.<?xml version="1.0" encoding="utf-8"?> 
2.<configuration>     
3.    <configSections
4.        ... 
5.        <section name="myCustomSection" type="MyApp.Configuration.DeptConfigurations" /> 
6.    </configSections
7.... 
8.</configuration>

This doesn't seem to affect the messages (not warnings/errors) regarding schema information for the elements and attributes when trying to compile.

  Adam Houldsworth replied to Jamie Gates
22-Mar-10 08:42 AM
Hi,

The configSection defines the name of the section in the XML - in your case "myCustomSection", and also the type name (including namespace) and assembly of where to find the type responsible for handling this custom section.

Your handler name and namespace look OK, but you appear to have omitted the assembly name in the second example:

<section name="myCustomSection" type="MyApp.Configuration.DeptConfigurations, AssemblyName" />

Note this needs to appear before your custom section does.

With this corrected, are you still getting errors?  If so, can you please post the code for handling the sections and some example XML?

Adam
  Jamie Gates replied to Adam Houldsworth
06-Apr-10 12:27 AM

I added the correct assembly name as you described, and I do still receive messages. I noticed I only get the messages when I open the app.config file; the messages go away when I close the file.

57 Messages: Culd not find schema information for the element 'myCustomSection'.

See the DeptConfigurations.cs class and XML from the app.config file below.

DeptConfigurations.cs

001.using System;
002.using System.Configuration;
003.  
004.namespace MyApp.Configuration
005.{
006.    public class DeptConfigurations : ConfigurationSection
007.    {
008.        //private static DeptConfigurations settings = ConfigurationManager.GetSection("myCustomSection") as DeptConfigurations;
009.  
010.        //public static DeptConfigurations Settings
011.        //{
012.        //    get
013.        //    {
014.        //        return settings;
015.        //    }
016.        //}
017.  
018.        // Create a "departments" element collection
019.        // containing "department" items/elements.
020.        [ConfigurationProperty("departments")]
021.        [ConfigurationCollection(typeof(DepartmentElementCollection), AddItemName = "department")]
022.        public DepartmentElementCollection Departments
023.        {
024.            get
025.            {
026.                return (this["departments"] ?? new DepartmentElementCollection())
027.                    as DepartmentElementCollection;
028.            }
029.        }
030.    }
031.  
032.     
033.    public class DepartmentElementCollection : ConfigurationElementCollection
034.    {
035.        public DepartmentElement this[int index]
036.        {
037.            get { return base.BaseGet(index) as DepartmentElement; }
038.            set
039.            {
040.                if (base.BaseGet(index) != null)
041.                    base.BaseRemoveAt(index);
042.  
043.                this.BaseAdd(index, value);
044.            }
045.        }
046.  
047.        // Create a "department" element
048.        protected override ConfigurationElement CreateNewElement()
049.        {
050.            return new DepartmentElement();
051.        }
052.  
053.        protected override object GetElementKey(ConfigurationElement element)
054.        {
055.            return (element as DepartmentElement).Name;
056.        }
057.    }
058.  
059.  
060.    // Define the "department" element
061.    // with "name" and "abbreviation" attributes.
062.    public class DepartmentElement : ConfigurationElement
063.    {
064.        [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
065.        public string Name
066.        {
067.            get { return this["name"] as string; }
068.            set { this["name"] = value; }
069.        }
070.  
071.        [ConfigurationProperty("abbreviation", IsRequired = true)]
072.        public string Type
073.        {
074.            get { return this["abbreviation"] as string; }
075.            set { this["abbreviation"] = value; }
076.        }
077.  
078.        // Create a "dbLocations" element collection
079.        // containing "dbLocation" items/elements.
080.        [ConfigurationProperty("dbLocations")]
081.        [ConfigurationCollection(typeof(dbLocationElementCollection), AddItemName = "dbLocation")]
082.        public dbLocationElementCollection DbLocations
083.        {
084.            get
085.            {
086.                return (this["dbLocations"] ?? new dbLocationElementCollection())
087.                    as dbLocationElementCollection;
088.            }
089.        }
090.    }
091.  
092.  
093.    public class dbLocationElementCollection : ConfigurationElementCollection
094.    {
095.        public dbLocationElement this[int index]
096.        {
097.            get { return base.BaseGet(index) as dbLocationElement; }
098.            set
099.            {
100.                if (base.BaseGet(index) != null)
101.                    base.BaseRemoveAt(index);
102.  
103.                this.BaseAdd(index, value);
104.            }
105.        }
106.  
107.        protected override ConfigurationElement CreateNewElement()
108.        {
109.            return new dbLocationElement();
110.        }
111.  
112.        protected override object GetElementKey(ConfigurationElement element)
113.        {
114.            return (element as dbLocationElement).Name;
115.        }
116.    }
117.  
118.  
119.    // Define the "dbLocation" element
120.    // with "name" and "value" attributes.
121.    public class dbLocationElement : ConfigurationElement
122.    {
123.        [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
124.        public string Name
125.        {
126.            get { return this["name"] as string; }
127.            set { this["name"] = value; }
128.        }
129.  
130.        [ConfigurationProperty("value", IsRequired = true)]
131.        public string Value
132.        {
133.            get { return this["value"] as string; }
134.            set { this["value"] = value; }
135.        }
136.    }
137.}

app.config

01.<?xml version="1.0" encoding="utf-8"?>
02.<configuration>    
03.    <configSections>
04.        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
05.            <section name="Launcher.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
06.        </sectionGroup>
07.        <section name="myCustomSection" type="MyApp.Configuration.DeptConfigurations, AssemblyName" />
08.    </configSections>
09.  
10.    <myCustomSection>
11.        <departments>
12.            <department name="Department 1" abbreviation="D1">
13.                <dbLocations>
14.                    <clear />
15.                    <dbLocation name="production" value="\\D1\fileshare\" />
16.                    <dbLocation name="test" value="\\D1\TestFileshare\" />
17.                </dbLocations>
18.            </department>
19.            <department name="Department 2" abbreviation="D2">
20.                <dbLocations>
21.                    <clear />
22.                    <dbLocation name="production" value="\\D2\fileshare\" />
23.                    <dbLocation name="test" value="\\D2\TestFileshare\" />
24.                </dbLocations>
25.            </department>
26.            <department name="Department 3" abbreviation="D3">
27.                <dbLocations>
28.                    <clear />
29.                    <dbLocation name="production" value="\\D3\fileshare\" />
30.                    <dbLocation name="test" value="\\D3\TestFileshare\" />
31.                </dbLocations>
32.            </department>
33.        </departments>
34.    </myCustomSection>
35.  
36.    <userSettings>
37.        <Launcher.Properties.Settings>
38.            <setting name="Environment" serializeAs="String">
39.                <value>Production</value>
40.            </setting>
41.            <setting name="ProductionDbLocation" serializeAs="String">
42.                <value />
43.            </setting>
44.            <setting name="TestDbLocation" serializeAs="String">
45.                <value />
46.            </setting>
47.            <setting name="Department" serializeAs="String">
48.                <value />
49.            </setting>
50.            <setting name="DeptAbbreviation" serializeAs="String">
51.                <value />
52.            </setting>
53.        </Launcher.Properties.Settings>
54.    </userSettings>
55.</configuration>

  Adam Houldsworth replied to Jamie Gates
07-Apr-10 03:49 PM
Hi Jamie,

I put your config code and config file content into my own dummy application - I had to remove the userSettings stuff.  I didn't need to make any changes (though I changed your uncommented Settings property to my own static GetConfig method) and it works.  Just for the record, I uncommented your code and that worked too.

The only thing I can think of is that it's this other userSettings code giving you the warnings.  Try removing this.

I can't seem to upload the files, if you can provide an email I can send them to you directly.

Adam
Nevermind  Nevermind
07-Apr-10 04:05 PM
Scratch my previous post, I was looking for error messages not normal messages - I ge these too.

This is because there is no schema file describing the structure of your XML.  You can safely ignore this, or optionally generate the schema.  On the config file in Visual Studio you will notice on your toolbar a button called 'Create Schema':



Almost too good to be true.  This will give you a rather horrendous looking XSD file.  Save this to a sensible location.

On your property page for your config file, enter the schema settings:



Select your file:



And then you will see that your messages disappear.

Adam
  Jamie Gates replied to Adam Houldsworth
07-Apr-10 11:06 PM

Got it, thank you! I had a feeling it had something to do with describing the structure of the XML.

Now, if only I can figure out how to read my new configuration settings...

I have tried multiple permutations to create a new object to read the department name based on the many articles I have read, but I keep getting the object with a null value which throws a NullReferenceException.

Some references I thought were useful:

http://msdn.microsoft.com/en-us/library/2tw134k3.aspx

http://nnish.com/2009/09/17/custom-configuration-section-in-c/

Here are some of the ways in which I have tried to read the first department name. The NullReferenceException is thrown at each of the variable declarations "string departmentNameX = ...".

01....
02.   
03.           /// TRY 1
04.            DepartmentElement department1 = new DepartmentElement();
05.            string departmentName1 = department1.Name;
06.  
07.              
08.            /// TRY 2
09.            MyApp.Configuration.DeptConfigurations department2 =
10.                (MyApp.Configuration.DeptConfigurations)System.Configuration.ConfigurationManager.GetSection(
11.                "myCustomSection/departments");
12.  
13.            string departmentName2 = department2.Departments[0].Name;
14.  
15.  
16.            /// TRY 3 
17.            MyApp.Configuration.DepartmentElement department3 =
18.                (MyApp.Configuration.DepartmentElement)System.Configuration.ConfigurationManager.GetSection(
19.                "myCustomSection/departments/department");
20.  
21.            string departmentName3 = department3.Name;
22.  
23.  
24.            /// TRY 4
25.            DeptConfigurations department4 =
26.                (DeptConfigurations)System.Configuration.ConfigurationManager.GetSection("myCustomSection/departments/department");
27.  
28.            string departmentName4 = department4.Departments[0].Name;
29.  
30.              
31.            //string departmentName1 = MyApp.Configuration.DepartmentElement;
32.            //string departmentName1 = ConfigurationManager.AppSettings.Get("name");
33.                //.DepartmentElement.Name;
34.            string abbreviation1 = "";
35.            //abbreviation1 = department1.Abbreviation[0].ToString();
36.  
37.            MessageBox.Show("departmentName: " + departmentName4 +
38.                Environment.NewLine +
39.                "abbreviation: " + abbreviation1);

  Adam Houldsworth replied to Jamie Gates
08-Apr-10 03:27 AM
Hi Jamie,

This attempt was your closest:

MyApp.Configuration.DeptConfigurations department2 =
    (MyApp.Configuration.DeptConfigurations)   
    System.Configuration.ConfigurationManager.GetSection("myCustomSection/departments"); 
    
string departmentName2 = department2.Departments[0].Name;

Change it to the following (note you only need to get down to your custom section, the section handler then queries deeper into the XML):

MyApp.Configuration.DeptConfigurations department2 = 
    (MyApp.Configuration.DeptConfigurations)    
    System.Configuration.ConfigurationManager.GetSection("myCustomSection");  
      
string departmentName2 = department2.Departments[0].Name;

Adam
Success  Success
08-Apr-10 07:15 AM

Well, I think I'm actually beginning to understand this. There have been a lot of new concepts introduced here, which will take a little more time to fully grasp, but this has been extremely helpful.

Here is what I have that is successfully querying the first department information. This has also identified how I may be able to loop through the departments to store them in my Department objects and do comparisons, etc.. Again, thank you very much for your help.

  01. ... 
02.              
03.            //// TRY 5 -- WORKING
04.            MyApp.Configuration.DeptConfigurations department5 =
05.                (MyApp.Configuration.DeptConfigurations)System.Configuration.ConfigurationManager.GetSection("myCustomSection");
06.  
07.            int numDepartments = department5.Departments.Count;
08.  
09.            string departmentName5 = department5.Departments[0].Name;
10.            string departmentAbbreviation5 = department5.Departments[0].Abbreviation;
11.            string departmentDbLocationProdName5 = department5.Departments[0].DbLocations[0].Name;
12.            string departmentDbLocationProdValue5 = department5.Departments[0].DbLocations[0].Value;
13.  
14.  
15.            MessageBox.Show("numDepartments: " + numDepartments +
16.                Environment.NewLine +
17.                Environment.NewLine +
18.                "departmentName: " + departmentName5 +
19.                Environment.NewLine +
20.                "departmentAbbreviation: " + departmentAbbreviation5 +
21.                Environment.NewLine +
22.                "departmentDbLocation: " + departmentDbLocationProdName5 +
23.                Environment.NewLine +
24.                "departmentDbLocationProd: " + departmentDbLocationProdValue5);

Create New Account
help
visual studio installation problem Actually, my OS is Windows Xp with service pack2.I added service pack3 to install visual studio2010.after that i tryed to installed, but am getting SETUP FAILED due to "Windows XP is not installed. [08 / 10 / 11, 14:26:00] VS70pgui: [2] DepCheck indicates Microsoft Visual F# 2.0 Runtime was not attempted to be installed. [08 / 10 / 11, 14:26:00] VS70pgui: [2] DepCheck indicates Microsoft Visual Studio Macro Tools was not attempted to be installed. [08 / 10 / 11, 14:26:00] VS70pgui attempted to be installed. [08 / 10 / 11, 14:26:01] VS70pgui: [2] DepCheck indicates Microsoft Visual Studio 2010 Professional - ENU was not attempted to be installed. [08 / 10 / 11, 14:26:01
NET 2003 Professional I had VS .NET 2003 Professional installed on my machine and also Visual Web Developer 2005 Express Edition. Both work and after a few days both stopped working This step-by-step article describes two methods that you can use to remove Microsoft Visual Studio .NET 2003 from your computer. Back to the top Back to the top Remove Visual Studio .NET 2003 by using the Add or Remove Programs tool loadTOCNode(2, 'summary'); To remove Visual Studio .NET 2003 by using the Add or Remove Programs tool in Control Panel, follow these double-click Add or Remove Programs . 3. In the Currently installed programs list, click Microsoft Visual Studio .NET 2003 , and then click Change / Remove . Follow the onscreen instructions to remove Microsoft
SharePoint 2010 Visual Web Parts using Visual Studio 2010, Feature Designer and Package Designer How to create a Visual Web Part in Visual Studio 2010 and how to deploy it to the SharePoint 2010 team site. What is a Visual Web Part? With SharePoint 2007 and Windows SharePoint Services 2007 or previous versions, to develop mistake while writing the design code could mess up the whole layout. But now using Visual Studio 2010, we can develop a custom web part for SharePoint 2010 site using the