Visual Studio 2010: Publish hangs

May 23, 2013

I noticed something weird the last couple of days, something I had never experienced before:

Select an ASP.Net MVC application in Solution Explorer, right-click and select Publish…

The Publish dialog opens, I select publish to File System and enter the target path.

The Build process starts and completes, but the last line that is displayed in the Output Window is

Connecting to C:\path\to\publish...

Then Visual Studio hangs at 100% CPU usage (or, 25% on a quad-core machine).

You can hit Ctrl-Break, and the break is indicated, but nothing else happens, and VS is busy burning CPU cycles.

Fortunately I found this entry on Connect, and the first Workaround immediately solved my problem:

Delete the .suo file!


On Converting Data

May 2, 2013

I had to analyze SQL Server Database Projects (available from SQL Server Data Tools for Visual Studio), and these projects offer a menu item “Create Snapshot” which creates a snapshot file with the extension .dacpac.

It turns out that a .dacpac is a zipped XML file (plus some other files) containing a structured representation of the database objects defined in the project. However Visual Studio does not provide a way to display them (double-clicking the file will only display binary data).

So I thought about how to best display the contents of a .dacpac? Two methods came to my mind.

First, inspired by my work on wpxslgui, create an XSLT style sheet which transforms the contents of the XML file to some legible text, for example CREATE TABLE and similar TSQL statements.

Intuitively I called this approach Symbolic Transformation.

Symbolic Transformation (e.g. XSLT)
Representation 1 => Representation 2

On the other hand, a Logical Transformation contains one module parsing the information contained in “Representation 1″ into some kind of model, and another module creating the “Representation 2″ of that model. The two module can be  implementations of the Interpreter pattern and the Builder or Factory patterns, respectively.

Logical Transformation (simple)
Interpreter Builder
Representation 1 => Model => Representation 2

If we take Representation 1 and Representation 2 as two separate interfaces to the same business model, and want to support two-way operations, we can extend the last table like this:

Logical Transformation (extended)
Interpr.
Builder
Converter Converter Interpr.
Builder
Repr. 1 => Model 1 => Business Model => Model 2 => Repr. 2
<= <= <= <=

Why do we need to have Model 1 and Model 2, as they seem to make the whole thing even more complex?

Let’s have a look at a simple CREATE TABLE statement and some of their representations:

  • a SQL parser (think: ANTLR) uses the representation given by the SQL parser
  • the SQL Server catalog views sys.tables, sys.columns, etc. are a different representation
  • a .dacpac archive is another representation

To keep our code simple, our Model X class structure should be as close to the representation as 1) possible 2) necessary (thinking about proxy classes generated by xsd.exe, ANTLR, and ORMs).

Thus, a common data model (named Business Model in the table) is required, as well as 2-way conversion between the Business Model and each of the other models.


Handling Web.Config Variants in Source Control-based Solutions

April 24, 2013

If several developers work on the same projects or solutions, sooner or later you need to manage the .config files of these developers (e.g. for local databases vs. team database, local log files and directories, and so on).

Of course, if you use a source control system, such as TFS or SVN, you don’t want the personal settings of one developer to overwrite the settings of another one.

Separate SCS config files

Usually my approach is to not check in the app.config or web.config files, but instead create copies of these files as config templates (e.g. web.tfs.config, app.svn.config) and have these copies under source control.

Recently I saw a big obstacle to this approach, and it is called TFS Team Build, an implementation of Continuous Integration.

I definitely wanted to avoid having to check out the config files, rename them so as to match the CI backend, build, and then revoke the check out.

User-specific config files

Next try, have app.config and web.config in separate sub-directories of each project, and simply copy the developer-specific app.config to app root before compilation.

While this works for app.config, it does not work for web.config in cases that the web.config contains an <authentication> element. Then the error is raised

Error 3 It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

(Yes, I encountered this error message before, and in that case you should be able to solve the problem by running Clean on the project or the solution)

Include user-specific config files using configSource

Next try, move all developer-specific (or installation-specific) config sections to separate .config files and include these .config section files using configSource.

When you’re done, your web.config will look something like this:

<configuration>
  <configSections>
  ...
  </configSections>
  <log4net configSource="Config\log4net.config" />
  <appSettings configSource="Config\appSettings.config" />
  <connectionStrings configSource="Config\connectionStrings.config" />
  <system.serviceModel>
    ...
    <client configSource="Config\system.serviceModel.client.config" />
  </system.serviceModel>
</configuration>

Copy the original contents of the web.config to the new files in the Config directory, e.g.:

<?xml version="1.0"?>
<connectionStrings>
    <add name="default" 
        connectionString="Data Source=localhost;Initial Catalog=cat;Persist Security Info=True;User ID=userid;Password=pwd" 
        providerName="System.Data.SqlClient" />
</connectionStrings>

The Config directories then further contains one directory for each developer or installation environment.

To activate one of these configurations, simply copy the config files of one directory into the Config directory, but do not check-in the changes in the Config directory itself.

You can also write a batch file to perform the copy statements and invoke the .cmd from Solution Explorer.

The only drawback I see with this solution is that you lose Intellisense with these partial config section files.

 


Some Visual Studio Items

April 24, 2013

Item Templates not found

After installing SSDT for VS and SSDT from Advanced Services, Visual Studio failed to add a New Item (in fact, any New Item regardless of the item type), instead displaying the error message that it ”could not find file” in the directory appdata\local\microsoft\visualstudio\10.0\itemtemplatescache…etc…

As this answer on SO explains, you need to run devenv.ex (from command line in administrator mode) using the /installvstemplates switch, to fix this error.

Run .cmd from VS

You add a .cmd file to your project or solution, and want to invoke it from inside the VS IDE?

I found this instruction to add cmd.exe as External Tool and assign its invocation to any file inside a project.

To open the command prompt in a separate console window (rather than pipe its output to VS’s Output Window), you need to uncheck the Use Output Window checkbox. You must uncheck it if the batch file contains input statements such as PAUSE.


Getting Started with Visual Studio 2010 and SSRS

April 23, 2013

If you wanted to develop for SQL Server 2008 SSRS, you needed to install BIDS 2008, which was essentially the Visual Studio 2008 shell plus some SSRS-related project types.

When migrating one of my SSRS projects to VS2010, I thought the only thing I needed to install additionally was SQL Server Data Tools and everything would be fine.

Oh noes! (If it was, I wouldn’t write this blog…)

I opened a solution containing an .rptproj file, and received the error message

‘name.rptproj’ cannot be opened because its project type (.rptproj) is not supported by this version of the application. To open it, please use a version that supports this type of project.

[Search mode on]

This answer on StackOverflow started my link hunt, which found the following blog posts (sure, there are even more out there), listed in no particular order

Essentially, the point is, there are two products named SSDT: Business Intelligence and VS support for SQL Server development. If we want to develop for SSRS, we need the BI flavor, which is NOT part of SSDT for VS2010.

SSRS for BI is included in SQL Server 2012, and in SQL Server Express with Advanced Services.

Knowing all that, we can even claim that MSDN said so:

In the SQL Server 2012 installer, developers can install the BIDS tools for Visual Studio 2010 by selecting SSDT during installation.  The BIDS tools will run on Visual Studio 2010 SP1, as SSDT does. The SQL Server 2012 installer will also install SSDT’s prerequisites and a “stub project” that allows SQL Server 2012 users to acquire the latest SSDT version from the web.

In the web acquision [sic! ??] experience, however, the SSDT shell only includes the database projects component. Installing SSDT from the web will not install BIDS tools.


Struggling with SSRS 2008 Error rsAccessedDenied on Win7

February 15, 2013

After successfully deploying a RDL report definition to SSRS 2008 running on Win7, I tried to browse the Report Server web under
http://localhost/ReportServer
but was greeted by the error message

Die dem Benutzer ‘machine\username’ erteilten Berechtigungen reichen zum Ausführen des Vorgangs nicht aus. (rsAccessDenied)

The permissions granted to user ‘machine\username’ are insufficient for performing this operation. (rsAccessDenied)

Navigating to the Report Manager under
http://localhost/Reports/Pages/Folder.aspx
gave me the message

Der Benutzer ‘machine\username’ verfügt nicht über die erforderlichen Berechtigungen. Stellen Sie sicher, dass ausreichende Berechtigungen erteilt und die Einschränkungen der Windows-Benutzerkontensteuerung (UAC) behandelt wurden.

User ‘machine\username’ does not have required permissions. Verify that sufficient permissions have been granted and Windows User Account Control (UAC) restrictions have been addressed.

Of course, the suggested Online “help” had not only no useful information, but really contained *nothing*at*all*.

I found this blog on rcAccessedDenied but at first could not really figure out what it meant. Especially since the described workaround (run browser as administrator, also mentioned by an illustrated DBA tip) did not work for me. At least, I figured out that I needed a “real” administrator account to proceed.

So I started Control Panel, Computer Administration, Local Users and Groups and double-click the Administrator account. I activated the account and set a password.

After this, I managed to log in to the Report Server web using the Administrator’s credentials. There I could assign roles to my usual Windows user, but the user was still unable to connect to both sites.

Using the Administrator login I could at least grant rights to browse the data sources folder under
http://localhost/Reports/Pages/Folder.aspx?ItemPath=%2fData+Sources&ViewMode=List
and the deployed reports under
http://localhost/Reports/Pages/Folder.aspx?ItemPath=%2f[SolutionName]&ViewMode=List
.

By the way, I tried running the browser as administrator on another computer (SQL Server 2012, SSRS, Win7) and was immediately able to browse the Reports/Pages/Folder.aspx. I really have no idea what’s going on here :(


Invoking Stored Procedures generating C# Code using T4 Templates

February 5, 2013

When developing database applications, I usually start out with the database schema and have the necessary C# code (data classes, procedure calls, application-specific constants) generated by a couple of stored procedures. For my own projects, I create a batch file to build the various parts of the solution, all the way from code generation to publishing the application.

Maybe not everybody shares my preference for building-by-batch, so I was looking for an alternative way to invoke code generation in stored procedures, and I remembered working on a project a couple of years ago that used T4 Text Templates to generate C# code.

The first component of the T4 solution is MultipleOutputHelper.ttinclude which implements features such saving only changed files, handling check-out if connected to TFS, and much more.

Since I want to access the connection strings stored in web.config or app.config, I searched for sample code and found ConfigurationAccessor.tt.

The final T4 Template looks like this. The header includes both libraries and declares .Net namespaces:

<#@ template debug="True" hostspecific="True" language="C#" 
#><#@ output extension=".cs"
#><#@ include file="MultipleOutputHelper.ttinclude"
#><#@ include file="ConfigurationAccessor.ttinclude"
#><#@ assembly name="System.Data"
#><#@ import namespace="System.Data"
#><#@ import namespace="System.Data.SqlClient"
#><#

Next, we instantiate the objects declared in both libraries

  var manager = Manager.Create(Host, GenerationEnvironment); 
  manager.StartNewFile("Classes.generated.cs"); 

  var config = new ConfigurationAccessor((IServiceProvider)this.Host);
  var connStrEntry = config.ConnectionStrings["default"];

Depending on your build process, you may want to cause database errors (connection string, connectivity, execution) to raise either warnings or compiler errors:

  var warnings = true;
  var errors = new List<string>();

  if (connStrEntry == null)
  {
    errors.Add("Connection string named 'default' not found");
  }
  else
  {
    var connStr = connStrEntry.ConnectionString;

After checking the connection string, let’s connect to the database and execute the stored procedure.

The output of PRINT commands is retrieved using the InfoMessage event:

    try
    { 
      using (var conn = new SqlConnection(connStr))
      {
        conn.Open();
        conn.InfoMessage += delegate(object sender, SqlInfoMessageEventArgs e)
        {                                    
            this.WriteLine(e.Message);
        };

        SqlCommand cmd = new SqlCommand("dev_Generate_DAL_Classes", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.ExecuteNonQuery();
      }
    }
    catch(Exception ex)
    {
      errors.Add(ex.Message);
    }
  }

  manager.EndBlock();

If no errors occurred, save the generated file. Otherwise, either raise warnings or errors.

  if (errors.Count == 0)
  {
    manager.Process(true); 
  }
  else 
  {
    foreach(var error in errors)
    {
      if (warnings)
        this.Warning(Host.TemplateFile + ": " + error);
      else
        this.Error(Host.TemplateFile + ": " + error);
    }
  }
#>

I originally tried to store warnings and errors using the Host.LogErrors method. However, no matter which Error Code I set in CompilerError, the result would always be errors rather than warnings. Using the TextTransformation‘s Warning() and Error() methods did the trick.


List of C# Compiler Errors

February 5, 2013

MSDN provides a list of C# Compiler Error Codes (VS 2003, VS 2005, VS 2008, VS 2010, VS 2012), but I could not find a complete list of error messages and descriptions.

So, for example, if you are looking for an appropriate error code you want to issue, you’d need to click through every error code until you find the correct one.

Fortunately, somebody (softwareAB, no affiliation) already compiled that data into a readable list, and provides the list of C# compiler error messages for download. (download saves as .txt, you need to rename the file to .html before viewing)

Thank you!


Automatically Compiling TypeScript in Visual Studio

November 9, 2012

After a bit of experimenting with TypeScript, I found two ways to automatically compile .ts to .js so far.

The first way is to create a project of type “HTML Application with TypeScript” and edit your TypeScript files there. Compiling the project will automatically generate the corresponding JavaScript files.

The advantage of this approach is that all your TypeScript code is kept in a separate project from your ASP.Net or ASP.Net MVC project.

But how do you get the compiled JavaScript files into your web project?

One solution is to set the project’s output directory to the script directory of your web project, and in Configuration Manager define the build order to build the TypeScript project before the web project.

For this method to work, the .js files generates by the TypeScript project must be included in the web project to be published.

But how does the TypeScript project know how to invoke the tsc compiler for .ts files? Well, it says so in the .csproj file by defining a BeforeBuild target:

<Target Name="BeforeBuild">
  <Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\
     TypeScript.8.0.0\tsc&quot; @(TypeScriptCompile 
     ->'&quot;%(fullpath)&quot;', ' ')" />
</Target>

If you copy this block to your web project’s .csproj file (unload project, edit project, reload project), it should make your existing project compile .ts files before invoking the regular C# build.

An answer on SO also suggest an extension that compiles on save, but this only works in VS 2012.


List Invalid Guids of Referenced Projects in VS Solution Dependency Visualizer 0.92

October 19, 2012

While preparing one of my projects for production, I came across a “funny” error:

While Visual Studio builds a solution without errors, msbuild raised the following error for an ASP.Net web application:

The type or namespace name ‘foo.bar’ does not exist in the namespace ‘foo’ (are you missing an assembly reference?)

I checked in Solution Explorer, and the project reference was clearly there, the assembly showed the namespace in ILSpy, and VS built the solution.

A little panicky, I removed the project reference and added it again. msbuild was now able to build the web application, but the build process raised solution file warnings:

c:\path\to\solution.sln : Solution file warning MSB4051: Project {Some-GUID-0001} is referencing a project with GUID {Other-GUID-0002}, but a project with this GUID was not found in the .SLN file.

Notice that the error message does NOT inform us while project contains the reference, and which other project was meant to be referenced, even though VS has all the necessary information to display the projects.

So I started another instance of VS, opened the VSSlnDep project, and added a new function, “List Invalid Guids of Project References”.

This function iterates through the project references of each project file (*.csproj, *.vbproj), and checks whether the referenced Guid is the project Guid of any project in the solution. If not, the reference is displayed using the referring and the referred project file names, along with both Guids.

To solve the invalid Guids, you need to navigate to the referring project in Solution Explorer, delete the project reference and add it again.

Conclusion 1: Visual Studio seems to resolve references using the project file name, whereas msbuild resolves using the project Guids.

Conclusion 2: Nobody knows why VS changes project Guids. Not even Microsoft.

As usual, the latest release of VS Solution Dependency Viewer is available for download here.


Follow

Get every new post delivered to your Inbox.