Shawn Wildermuth

Author, Teacher, and Filmmaker
.NET Foundation Board Member

Forcing ASP.NET WebForms Designer Files to Regenerate

Forcing ASP.NET WebForms Designer Files to Regenerate

This is going to be a relatively short post. I've been working with a company on merging their ASP.NET WebForms project with their MVC project. It's been an experience.

This is mostly because the original project was a Web Site, not a Web Project so that the .aspx files weren't compiled ahead of time. Merging these two projects, I wanted to be able to move to a Web Project + MVC to get a compilation step as a benefit.

The project is quite large and has been mostly straightforward except for User Controls. The problem is that once we moved to compiled User Controls, there was a bunch of naming changes to be made. That's all and good but Visual Studio was doing it really slowly and making me a little crazy. Part of this was because it was regenerating the Designer files for me. I thought I was smarter and did a bunch of renaming outside of Visual Studio. I wasn't.

I ended up with lots and lots of errors because the .aspx pages were out of sync with the designer files. Since there are nearly 200 files, the prospect of opening, changing, and saving each file to get a new designer file was out of the question.

Luckily for me, I am on Twitter.

I reached out and Mick Lang saved my butt. If you're like me, you might remember when Visual Studio supported Macros. Mick reminded me that you could install an addin to get that functionality back:

Macros for Visual Studio

Once I installed the macro, I reworked one of the examples to walk through my entire project and force all the designer files to re-generate. I thought someone out there might need this script. Here it is:

// Based on the Headify example from https://github.com/Microsoft/VS-Macros

// Iterate over all files
iterateFiles();

function iterateFiles() {
  for (var i = 1; i <= dte.Solution.Projects.Count; i++) {
    iterateProjectFiles(dte.Solution.Projects.Item(i).ProjectItems);
  }
}

function iterateProjectFiles(projectItems) {
  for (var i = 1; i <= projectItems.Count; i++) {
    var file = projectItems.Item(i);

    if (file.SubProject != null) {
      formatFile(file);
      iterateProjectFiles(file.ProjectItems);
    } else if (file.ProjectItems != null && file.ProjectItems.Count > 0) {
      formatFile(file);
      iterateProjectFiles(file.ProjectItems);
    } else {
      formatFile(file);
    }
  }
}

function formatFile(file) {
  dte.ExecuteCommand("View.SolutionExplorer");
  if (file.Name.indexOf(".aspx", file.Name.length - ".aspx".length) !== -1) {
    file.Open();
    file.Document.Activate();

    // Add a space
    Macro.Inser
    dte.ActiveDocument.Selection.StartOfDocument(false);
    dte.ActiveDocument.Selection.Insert(" ");

    // Remove a Space
    dte.ActiveDocument.Selection.StartOfDocument(false);
    dte.ActiveDocument.Selection.Delete(1);

    // Save the document
    file.Document.Save();
    file.Document.Close();
  }
}

If you read the code, you should see that it iterates through all files and then calls formatFile(). In format file, I confirm it's an .aspx file and then just add a space to the top of the file...delete that space (to force the file to be changed) then save and close it (which re-generates the designer file).

Ran this and waited the requisite 20 minutes it to complete and voila.

No one loves working on legacy projects, but I am happy to be able to help my clients with weird and crazy fixes like this.

HTH