Friday, January 7, 2011

Workaround for batch copy from Find Symbol Results window

Visual Studio 2008 and 2010 do not provide any easy way to export or shift-select the results in the Find Symbol Results window.  I ran into a situation where I needed to copy and paste 550 matches so I needed an automated solution.

I resolved this problem using a simple macro created in Macro Express (which offers a 30 day free trial) to copy one line at a time from the Find Symbol Results window into a Notepad document.  Download a copy of the macro I used here.

Wednesday, January 5, 2011

Resolution of Telerik RadPanel error due to upgrade to .NET Framework 4.0

One of our ASP.NET applications developed a bug after upgrading to the .NET Framework 4.0.  We use a Telerik RadPanel for web site navigation and we discovered that an error would occur when clicking on any RadPanel element, but only when the user opened the site to the default URL without specifying a page.

Example:
http://mysite.com/  - produces the error
http://mysite.com/default.aspx  - no error occurs

Here is the error message:

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB6.3; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0; .NET4.0C; .NET4.0E)
Timestamp: Wed, 29 Dec 2010 20:43:39 UTC
Message: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.
Details: Error parsing near '
<!DOCTYPE html P'.
Line: 6
Char: 84093
Code: 0
URI: http://mysite.com/Telerik.Web.UI.WebResource.axd?_TSM_HiddenField_=ctl00_RadScriptManager1_TSM&compress=1&_TSM_CombinedScripts_=%3b%3bSystem.Web.Extensions%2c+Version%3d4.0.0.0%2c+Culture%3dneutral%2c+PublicKeyToken%3d31bf3856ad364e35%3aen-US%3a1f68db6e-ab92-4c56-8744-13e09bf43565%3aea597d4b%3ab25378d2%3bTelerik.Web.UI%3aen-US%3af4b6e7a5-697d-4c2b-91aa-e1490df08c78%3a16e4e7cd%3af7645509%3aed16cbdc%3a24ee1bba%3a1e771326%3a4cacbc31

The solution is to add a "managedHandler" preCondition attribute to the Telerik RadCompression module in the web.config file, system.webserver/modules section.

  <system.webServer>
<
validation validateIntegratedModeConfiguration="false"/>
<
modules>
<
remove name="RadUploadModule"/>
<
add name="RadUploadModule" type="Telerik.Web.UI.RadUploadHttpModule" preCondition="integratedMode"/>
<
remove name="RadCompression"/>
<
add name="RadCompression" type="Telerik.Web.UI.RadCompression" preCondition="integratedMode,managedHandler"/>
</
modules>
</system.webServer>


Here are links to the articles that describe the problem and solution, give more information on the "add" element, and provide a great explanation of IIS7 PreConditions.

Monday, January 3, 2011

Leverage Web.config Transformation and external config files

I recently educated myself on this topic from several good online articles including MSDN and blog posts from Scott Guthrie, Scott Kirkland and Vishal Joshi.  The only major limitation I can discover in this wonderful new feature is that the web.config transformation is not invoked by debugging in Visual Studio, as explained in this asp.net forums post and elsewhere.

This limitation poses a problem for my shop and I’m sure is a frustration for any other shop with multiple developers and source code control.  In our case, we have the following requirements:

  • A set of “shared” appSettings that do not change regardless of deployment environment (debug/staging/release etc.)
  • A set of appSettings that do change for each deployment environment
  • Connection strings that change for each deployment environment

The appSettings that do change for each environment and the connection strings need careful management in source code control to avoid conflicts.  Initially I had planned to put the “shared” appSettings into the primary web.config file and then append the variable appSettings using the transformation process.  My primary web.config file and deployment environment transformation config files all would be managed using source control, and in addition each developer would have a sandbox transformation config file not under source control.  I would use a similar strategy for the connectionStrings section.  Unfortunately this strategy fails because the transformation is not invoked by debugging.

My solution is to use a combination of custom config sections, external config files, and transformation to meet all of my shop’s needs.  My solution results in more files to manage than the setup I wanted to use, but is still very manageable. 

This post provides a simplistic example with only Debug and Release configurations, but this concept can be scaled to any number of build configurations.  Here is a screen shot of a sample solution:

SolutionExplorer

Here is the Web.config file, which is used for Visual Studio debugging.  Note the custom “sharedSettings” section containing key/value pairs that do not change regardless of deployment environment and the use of external config files for the appSettings and connectionStrings sections.

<?xml version="1.0"?>
<
configuration>
  <
configSections>
    <
section name="sharedSettings" type="System.Configuration.NameValueFileSectionHandler"/>
  </
configSections>
  <
connectionStrings configSource="ConfigFiles\connectionStrings.Debug.config" />
  <
appSettings configSource="ConfigFiles\appSettings.Debug.config" />
  <
sharedSettings>
    <
add key="SharedKeyOne" value="Shared1" />
  </
sharedSettings>
  <
system.web>
    <
compilation debug="true" targetFramework="4.0" />
  </
system.web>
  <
system.webServer>
     <
modules runAllManagedModulesForAllRequests="true"/>
  </
system.webServer>
</
configuration>

Here is the Web.Release.config transformation file – transformations are used to update the connectionStrings, appSettings, and compilation debug settings.

<?xml version="1.0"?>
<
configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<
connectionStrings xdt:Transform="Replace">
<
add name="MyConnection" connectionString="my RELEASE connection string" providerName="System.Data.SqlClient"/>
</
connectionStrings>
<
appSettings xdt:Transform="Replace">
<
add key="KeyOne" value="Release1" />
<
add key="KeyTwo" value="Release2" />
</
appSettings>
<
system.web>
<
compilation xdt:Transform="RemoveAttributes(debug)" />
</
system.web>
</
configuration>

The Web.config and Web.Release.config files are managed under source code control.  The appSettings.Debug.config and connectionStrings.Debug.config files are customized locally by the developer and are not managed under source code control.