ControlDesigner - Accessing Web.Config at Design Time
TechEd Europe is quite cool till now. Some interesting sessions (especially things about Team System and Web Services) and - if you have read one of my older blog entries - I am at the ask the experts getting some interesting questions from attendees. Well, one of the more interesing questions I got was how to access the web.config through an Add-In or Control Designer at design time from within Visual Studio .NET. Therefore I decided to publish some code to demonstrate that.
When you are writing an Add-In for Visual Studio .NET you have a complete object model for accessing all the functions provided by Visual Studio. The object model for the development environment is called DTE (Design Time Environment) and currently only available through COM-Interop (add a reference to the COM type library "Microsoft Development Environment 7.0"). Just look for "DTE" in the MSDN library and you'll find some interesting entries. Now take a look at the following code (which is nothing else than a control designer for a custom ASP.NET web control) - which acutally is the answer for the question I got at the booths:
public class TestControlDesigner : System.Web.UI.Design.ControlDesigner
{
public override string GetDesignTimeHtml()
{
string html = "found nothing";
try
{
// Go through the design time environment, look for the config and read some data
EnvDTE.DTE devenv = null;
devenv = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
Array projects = (System.Array)devenv.ActiveSolutionProjects;
if((projects.Length == 0) || (projects.Length > 1))
{
html = "Exactly one project must be active";
}
else
{
// go through the items of the project to find the configuration
EnvDTE.Project project = (EnvDTE.Project)(projects.GetValue(0));
foreach(EnvDTE.ProjectItem item in project.ProjectItems)
{
// if it is the configuration, then open it up
if(string.Compare(item.Name, "web.config", true) == 0)
{
System.IO.FileInfo info =
new System.IO.FileInfo(project.FullName);
html = "<b>Found configuration</b>";
html += "<br>" + GetConfigSetting(
info.Directory.FullName + "\\" + item.Name);
}
}
}
}
catch(Exception ex)
{
html = "Exception occured: " + ex.Message;
}
return html;
}
private string GetConfigSetting(string fileName)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(fileName);
System.Xml.XmlNode node = doc.SelectSingleNode("//appSettings/add[@key='mySetting']");
if(node == null)
return "<font color='red'><b>missing configuration</b></font>";
else
return string.Format("<font color='blue'><b>setting value: {0}</b></font>", node.Attributes["value"].Value);
}
}
This is a Control Designer for my custom control that needs to access information in web.config at design-time. The GetDesignTimeHtml() method returns the HTML code that will be displayed by the VS.NET designer when the control is dropped onto a UserControl or a web page. Through the following code I get access to the currently running instance of Visual Studio:
EnvDTE.DTE devenv = null;
devenv = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
As soon as I got the instance of the development environment I can start getting the active projects and iterating through the project items. One of these items must be the web.config file of the web application (or it might be the app.config of a Windows Forms app). As soon as I have found the configuration file I can parse it through an XmlDocument - unfortunately no classes for modifying configuration files are included with .NET 1.1.
Array projects = (System.Array)devenv.ActiveSolutionProjects;
if((projects.Length == 0) || (projects.Length > 1))
{
html = "Exactly one project must be active";
}
else
{
// go through the items of the project to find the configuration
EnvDTE.Project project = (EnvDTE.Project)(projects.GetValue(0));
foreach(EnvDTE.ProjectItem item in project.ProjectItems)
{
// if it is the configuration, then open it up
if(string.Compare(item.Name, "web.config", true) == 0)
...
}
}
Debugging the control designer
Unfortunately if you start debugging you will not be able to place controls onto web pages of your test web application as long as the IDE is in debug mode. Therefore for debugging a control designer for a web control you will have to open up a separate IDE with just the control project and attach to the other IDE which has the web project opened that uses the control - attach for debugging CLR code. Then switch to the other IDE, open web page designer and add the control to the page. The second IDE will switch to debugging mode (of course don't forget to set a breakpoint) and you will have the chance to debug the control designer.
Comments
- Anonymous
June 30, 2004
I prefer to get the reference to the DTE like this:
EnvDTE.DTE _dte = (EnvDTE.DTE )Site.GetService(typeof(EnvDTE.DTE )); - Anonymous
June 30, 2004
Cool - but this would render a control incompatable with Web Matrix, wouldn't it? - Anonymous
July 06, 2004
Wow, I looked all over the web and newsgroups for how to do this. And I wasn't alone, there were countless newsgroup posts asking how to do it, and they were all unanswered, or answered incorrectly.
Thanks a bunch! - Anonymous
July 14, 2004
FYI - I used this code to create the designer support I was seeking for my ASP.NET 2.0 server control. It renders a UI for your personalization settings stored in the new Profile class. The source code includes a credit and link to this page.
http://flimflan.com/blog/archive/2004/07/07/188.aspx
Thanks again! - Anonymous
December 19, 2004
Ping Back来自:blog.csdn.net - Anonymous
February 07, 2006
&nbsp;
Quando desenvolvemos Type Editors ou simplesmente custom web Controls este é um bom problema... - Anonymous
June 17, 2009
PingBack from http://thebasketballhoop.info/story.php?id=2469