Monday, October 28, 2013

500.22 HTTP Error After Implementing Bundles in Web Forms Application and Publishing to IIS

So that was a very long title, but this really threw me for a loop. I implemented bundling via the Microsoft ASP.NET Web Optimization Framework NuGet package and it worked great in my ASP.NET development web server. The issue came when I deployed the site to the (previously working) development environment running IIS 7.5. All of the CSS and JS files referencing the bundles returned 404 errors. I looked through the Web.config and verified that everything was correct. I put Event Log entries into the Global.asax and found that they were all adding as expected.

I did some digging through Google but the number of people adding Bundles to their Web Forms application is smaller than I had expected and didn't find to much (nothing useful). Not having setup the environments, I thought that would be a great place to investigate further.

Investigating the web site in inetmgr, yielded nothing out of place. I am not sure why I looked at the application pool, but I did, and noticed that the pipeline was set to Classic, so I tried changing it to Integrated (just trying something). When I refreshed the page, I received a 500 HTTP internal server error and no other information. There was no information in the Event Log and the debugger never caught any breakpoints.

I went back to inetmgr and I turned on logging, recreated the error, and looked at the log. I found that the status code was 500 and the sub-status was 22 (500.22). This was a key bit of information. Googling this code yielded gold. I found this site, ASP.NET 2.0 Breaking Changes on IIS 7.0, which contained the status code I was looking for. Below is the important section:
1. ASP.NET applications require migration when specifying configuration in <httpModules> or <httpHandlers>

You will receive a 500 - Internal Server Error. This can include HTTP Error 500.22, and HTTP Error 500.23: An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode. This occurs because ASP.NET modules and handlers should be specified in the IIS <handlers> and <modules> configuration sections in Integrated mode.

Workaround

A. You must migrate the application configuration to work properly in Integrated mode. You can migrate the application configuration with AppCmd:

> %windir%\system32\inetsrv\Appcmd migrate config "<ApplicationPath>"

B. You can migrate manually by moving the custom entries in in the <system.web>/<httpModules> and <system.web>/<httpHandlers> configuration manually to the <system.webServer>/<handlers> and <system.webServer>/<modules> configuration sections, and either removing the <httpHandlers> and <httpModules> configuration OR adding the following to your application’s web.config:

<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>

I opted for the first part of B. The latter part may have been a little easier, but the first part seemed cleaner.

Refreshing the page allowed the bundles to be served up without issue. Apparently the Microsoft ASP.NET Web Optimization Framework requires the application pool to be in Integrated mode. That was a very weird error and obscure solution.

Tuesday, October 15, 2013

Reflections: Table Based Layout To Responsive Design Layout Conversion

I recently had the pleasure of converting a web application to a responsive design layout. The goal was to only change the structure of the HTML. I was able to stick to this with the exception of the Modal Popup Extender, but the changes were very minimal.

Considerations

  • Used the Modal Popup Extender
  • XHTML
  • CSS files, inline CSS styling, HTML style tags
  • Ridged table layout
  • All buttons are images

Expected Outcome

  • Use Bootstrap 2.3.x
  • HTML5
  • Responsive design layout
  • Must maintain support for IE8+ (potentially IE7)
  • Layout organization and text should be as close as possible to the original. Styles and structure implementation will be completely different.
  • Limit the code changes as much as possible.

The update process

The update process had a logical progression. Below I detail the highlights.


Update master page

I thought it was important to start with the master page; seemed logical. Below is the highlights on the things that I updated.

  1. Update the DocType
  2. Add meta tags
  3. Add new style tags to Bootstrap styles and place a ContentPlaceholder for styles after it
  4. Remove any tags which don't have 'runat="server"' or isn't a control. Leave the content.
  5. Put the content in the following div tag: <div class="container">
  6. Structure the header area
  7. Convert the menu bar/navigation section to the Bootstrap navbar
  8. Implement the design with Bootstrap design patterns/style
  9. Add Bootstrap scripts to the bottom of the page and place a ContentPlaceholder for scripts after it

The beginning of the page is the pretty boilerplate. I do as much as possible to promote other developers putting style code at the top of the page and the scripts at the bottom of the page. With Web Forms, this isn't always possible, but I try to stick to it when possible.

<!DOCTYPE  html>
<html lang="eng">
<head id="header" runat="server">
    <meta charset="utf-8" />
 <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible" />
 <meta content="on" http-equiv="cleartype" />
 <meta content="True" name="HandheldFriendly" />
 <meta content="320" name="MobileOptimized" />
 <meta content="width=device-width, initial-scale=1" name="viewport" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <link rel="apple-touch-icon" href="iphon_tetris_icon.png"/>
    <link rel="apple-touch-startup-image" href="startup.png" />
 <title />
    <link rel="stylesheet" href="/Content/style.css" type="text/css" />
    <asp:ContentPlaceHolder ID="StylesPlaceHolder" runat="server" />

I put the following .snippet as close to the bottom of the page as possible.

<script src="/bundles/bootstrap.js"></script>
<asp:ContentPlaceHolder ID="ScriptPlaceHolder" runat="server" />

Update ASPX pages and User Controls

The process for updating the rest of the pages and user controls were pretty consistent.

  1. Remove any tags which don't have 'runat="server"' or isn't a control. Leave the content.
  2. Reimplement the design with Bootstrap design patterns/style
  3. Move any needed scripts specific for that page to the scripts placeholder

Updating Modals

These are in the ASPX pages and User controls, but I thought it deserved a separate section because the process is a bit more involved. It assumes that the above points have been completed on the modal sections.

There were 2 different processes for this.

  1. Modal which can be populated at page load
  2. Modal which must be populated with information from an item select from a grid view

Below is the general process for converting the modals.

  1. Remove the Modal Popup Extender tags and any dummy links tied to it.
  2. Implement the design with Bootstrap design patterns/style. Below is a template.
    <div class="modal fade" style="display: none" id="pDemo" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
     <div class="modal-dialog">
     <div class="modal-content">
      <div class="modal-header" style="vertical-align: middle">
       <asp:Button ID="Button3" class="close" data-dismiss="modal" aria-hidden="true" Text="×" runat="server" />
       <h4 class="modal-title">Header Text</h4>
      </div>
      <div class="modal-body form-horizontal">
       <!-- Modal Content -->
      </div>
      <div class="modal-footer">
       <div class="control-group">
       <div class="controls">
        <asp:Button ID="btnSave" CssClass="btn btn-success" Text="Save" OnClick="btnSave_Click" runat="server" />
        <asp:Button ID="btnClose" CssClass="btn" data-dismiss="modal" Text="Close" runat="server" />
       </div>
       </div>
      </div>
     </div>
     </div>
    </div>
    
  3. IF the data was already loaded at the page load, update the link like the following:
    <a data-toggle="modal" href="#pDemo">
    
    There can be other attributes in the link, but the "data-toggle" and the "href" are the important points.
  4. IF the data needs to be loaded, wrap the modal in an UpdatePanel and follow the pattern in my previous blog post Handling Twitter Bootstrap Modals and UpdatePanels with PostBacks. If you can get into the code more than I could, you could omit a bunch of JavaScript using the following link in your code behind:
    AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript(this, typeof(System.Web.UI.Page), "pDemo", "$('#pDemo').modal('show');", true);

There are other little things, but these were the most important parts.

All in all, I found the conversion to be very easy to implement and it gave the old page layout a new breath of life.

Thursday, October 3, 2013

XCode development with Team Foundation Server

Occasionally, I do work on multiple platforms and historically mixed development has been an issue when your environment requires TFS. However, with TFS supporting Git, it should make that development much easier. I just ran across a couple posts that with instructions on how to use TFS w/ XCode and thought I would share.

Microsoft has a page dedicated to making this happen: (UPDATE: 2016-05-05, Microsoft moved the page) https://www.visualstudio.com/get-started/code/share-your-code-in-tfvc-xcode http://tfs.visualstudio.com/en-us/learn/use-git-and-xcode-with-tfs.aspx . I don't have a Team Foundation Server at my disposal, but it looks like you should be able to do this with onsite Team Foundation servers.

In projects with .Net code and iOS (and/or potentially Android), it might be a good idea to keep the code in separate repositories. It appears that Team Foundation Server 2012 supports multiple Git repositories with a single TFS team project.

http://stackoverflow.com/questions/17591461/can-you-add-multiple-git-repositories-to-a-team-project-in-tfs-tfs-service
You can create multiple git repositories under a single Team Project. Navigate to the Code Explorer, and locate the repository chooser in the web interface and select Manage Repositories...

<repository chooser image>

From the repository manager, you can add a new repository:

<team Project Version Control tab image>

This, of course, is provided that the Team Project uses Git as the version control provider - you can't mix and match Git repositories and Team Foundation Version Control in a single Team Project.

If you have an existing project w/ TF source control, you are out of luck. You can't do multiple TF SC repositories or have a TF and Git repository, so the only option is Git for this.

It is nice to see Microsoft embracing an incredibly powerful tool like Git. Just need to be weary about them reverting back to the days of the 3 E's.