Kevin Grohoske

Senior Software Engineer 
MCPD-WEB, MCPD-WIN, MCSD

Debugging Classic ASP With Visual Studio 2008 SP1 and 3.5 Framework

Thursday, April 30, 2009 06:22 | posted by: kevin

As much as I’d like never to debug complicated classic ASP code again, the fact is it’s everywhere in the enterprise today. Here is one way that I have found to speed up the process of supporting classic ASP w/ VS 2008 SP1/3.5.

At the last User Group meeting, I presented the features in the VS08 SP1 and 3.5 Framework. One topic/feature was only lightly covered in the documentation, but really jumped out at me, was that with Visual Studio 2008 SP 1 and 3.5 Framework VS 2008 can debug classic ASP code (script). I tried to find more information online, but the details were hard to find.So after a bit of research and trial and error I am sharing what I learned with you!

Here’s How:

1. Allow Server Side Debugging inside IIS Manager for the web site.

IIS Manager Settings

2. Open the Web Site in VS 2008 IDE by File - Open - Web Site and browsing to the directory that the IIS’s web is pointed to.

Open Web Site

3. Accept FrameworkUpgrade Warning (if prompted).

Framework Upgrade Warning

4.  Configure Web Site Startup Properties to open correct website through IIS url (http://localhost/…)

Web Site Properties

5.  Run Web Site in Debug Mode (F5) and accept Web.Config warning.

Allow .NET Debugging

6. In VS 2008 IDE Debug Menu select Attach To Process and choose the dllhost.exe process

Attach to dllhost.exe process

7. Begin Debugging By Setting Breakpoints in the IDE.

Visual Studio 2008 Debugging

That’s is !!! Ok so what changes were made to the original process?

When you exit the it VS 08 will prompt you to save a solution file.

And… A web.config for the .NET Debugger will be created in the root of the web. You should remove it when you deploy to production.

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

On Tuesday I presented, “Getting the Most Out of SharePoint” at the Web Technologies Conference in Spanish Fort, AL, which was co-sponsored by Microsoft, The Gulf Coast Technology Conference, and Bit-Wizards.

Despite a few technical glitches and last minutes emergencies, the entire day went very well. I received a ton of very positive feedback about how the presentation had a good balance between technical and ‘C’ business type level content, which is great because that was the tightrope I was trying to walk. If you’ve never given a technical presentation, you can’t appreciate how difficult it can be to find the right balance.

During intermissions I had a great time mingling and telling old war, IT horror, and Cincinnati/Dayton stories with attendees. I hope we get to do more of these because SharePoint adoption is growing by leaps and bounds, but in the haste to implement too many people (IT and Business teams) are painting themselves in a corner or not getting the ROI they could, thus it becomes SharePoint’s fault.

I don’t think we’ve published our slide deck yet so below are highlights of my presentation:

SharePoint should become the hub of your business activity-

  • The built-in resources/features should be leveraged for all future Intranet applications.
  • Imagine productivity gains by not having to start from scratch security/reporting/search/workflow/forms when developing Line of Business (LOB) applications
  • If you dream it… it can be done.

Have A Plan -

  • It is not just an application you install and run with - that is the recipe for failure Business and IT Stake Holders should be involved Develop and communicate the following:
    • Governance Document
    • Business Requirements
    • Project Plan
    • Project Design
    • Branding Design
    • Training Plan

Integrate it with Existing Applications and Data Extend ROI by keeping existing business systems - 

  • Any line of business (LOB) application that .NET technologies can communicate with can be integrated with SharePoint
  • You can integrate existing web applications or use the underlying data in SharePoint
  • Let SharePoint be the ecosystem for your Intranet applications

Brand Your SharePoint - It’s not a question of Fashion or Function – you can have both

  • Out of the box SharePoint 2007 looks dated and plain
  • Branding will help ‘sell’ SharePoint up and down the organization chart
  • For extranets you can extend your corporate brand to vendors and outside companies alike

Microsofts’ SharePoint is the 800lbs gorilla and will continue to get better.

  • Fastest growing server product
  • 100+ million licenses sold
  • 1 billion in revenue in FY08
  • Growth of 35% over FY07

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

Visual Studio 2008 SP1 & Framework 3.5.1 Features Presentation

Friday, March 06, 2009 06:15 | posted by: kevin

At the last Gulf Coast .NET User Group, I presented the following slides. There are a number of great features in Service Pack 1 release of VS 2008 and 3.5.1 Version of the .NET Framework. Here are couple quick things to keep in mind.

  •  VS 2008 SP1 and 3.5.1 Framework are pretty much a lockstep upgrade.
  • I call the framework 3.5.1 because MS released a service pack for the framework soon after releasing 3.5.
  • MVC is not part of this release of the framework and is still a separate install. It will likely be a part of 4.0 Framework due out this year.

Visual Studio SP & .NET 3.5.1 Framework Features Presentation

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

A long time ago before the world of Visual Studio’s Integrated Web Server and .NET you had to test web sites a bit more “manually”. Here is one trick that is a somewhat lost art.

If you want to test your web application and/or web service (very handy trick for web services)  for some reason you need it to be at a specific URL, such as http://www.testingURL.com. You will need to assign a separate IP address for your web site/webservice.

On windows servers and desktops, you can modify the “hosts” file (note there is no file extension). If you have not modified this file it should look like the following:

# Copyright (c) 1993-1999 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a ‘#’ symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

127.0.0.1       localhost

To add a new entry simply type the ip address of the actual location of the test web site/web service you are working with (ex.  222.22.22.222). And then type the “fake” name of the URL (ex. testingURL.com)

With the above information your entry into the “hosts”:

222.22.22.222    testingURL.com

Once you save this file all requests for testingURL.com will now go to the ip address 222.22.22.222.

The beauty of this solution is that you can bind a WS call to your production web service while developing and all requests get routed to your test web service! Once in production, all the calls will be routed to your production web server.

On Windows 2003 and XP the “hosts” file is located at -  C:\windows\system32\drivers\etc

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

Creating and Displaying Dynamic Serverside Error Messages with MS Ajax

Tuesday, August 26, 2008 05:25 | posted by: kevin

Thank you Keith Brooks for contributing to this article.

If you have ever tried to capture exceptions in your codebehind and display friendly messges the users using Microsoft’s AJAX toolkit, you may find the very simple idea becomes complicated very quickly. I ran into this when I had some projects that I wanted to AJAX’ify by using a typical alert method that registered a block of client side javascript and was fired on the pages Load event, but found that method failed when using AJAX.

Let me explain why… when a normal ASP.NET page renders it goes through a typical a Page Life Cycle . For normal page lifecycle, the script blocks are written to the client during the Initialization event and once complete the Load event code executes.

However, with a ASP.NET AJAX that page life cycle is somewhat different. On the initial page load, the page loads using the standard ASP.NET Page Lifecycle; however, when posting data back to the server using an AJAX update panel not all of the page is being sent back to the server, hence the AJAX. Because of this when the AJAX post to the server is complete, the entire page is not re-rendered. Only the contents of the update panel is updated and no page level Load event fires.

Here lies the issue. Since the page does not completely re-render and there is no client side Page Load event after the postback, many of the old scripts for displaying error messages do not work.

Ok. Enough of the lecture. You probably want to learn the solution.

There are a few parts to this solution. First, the ScriptManager object has a relatively obscure property called “onasyncpostbackerror”. This property represents the code behind function (server side) that gets fired when an exception happens during a post back. So the first step is to register a function using this property.

<asp id="ScriptManager1" runat="server" onasyncpostbackerror="ScriptManager1_AsyncPostBackError"></asp>

Next step is to write the code behind’s AsyncPostBack error method. In my case, I had already handled the exception, wrapped it, and threw the user friendly exception, therefore this was all I needed in my code behind. Realize that you must raise the exception and leave it unhandled for it to bubble up to the Script Manager’s event to handle it.

protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
{
ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message;
}

Here is a simple demonstration of how I set up forced the exception.

protected void Button1_Click(object sender, EventArgs e)
{
try
{
DoingSomething();
}
catch (Exception ex)
{
throw new Exception("The system has encountered problems, please notify your administrator or try again.", ex);
}
}
private void DoingSomething()
{
throw new Exception("inner exception message");
}

Now back to the client side of the example. I have to register an event in javascript to handle the ‘EndRequestHandler’ event created by the AJAX post back. This event fires upon the return on the post back to the client and I also added some features to remove the default exception, “Sys.WebForms.PageRequestManagerServerErrorException:”, and I’m displaying the Exception using a Panel control and the ModalPopupExtender (shown below) using the MS AJAX ModalPopupExtender object.

Sys.WebForms.PageRequestManager.getInstance().
add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args)
{
if (args.get_error() != undefined && args.get_error().httpStatusCode == '500')
{
var errorMessage = args.get_error().message
errorMessage = errorMessage.replace('Sys.WebForms.
PageRequestManagerServerErrorException:', "");
args.set_errorHandled(true);
$get("txtAlertMessage").innerHTML = errorMessage;
$find("ModalAlertDialogBehavior").show();
}
}

Here is the source of the Panel I use and the ModalPopupExtender:

{Note: for the the modal dialog extender you need to bind the control to a button, but that button may be hidden, as you will see in my source code. I call the Show() method of the Modal Dialog’s Behavior. You do not call show on the modal dialog object itself.}

<asp:Panel ID="AlertPanel" runat="server" CssClass="modalPopup">
<asp:Panel ID="AlertPanelContent" runat="server" >
<table class="AlertTable">
<tr class="AlertRow" height="20px">
<td class="AlertTitle" height="20px">
<center>
<asp:Label ID="lblAlertTitle" runat="server" Text="Label" height="20px"/>
</center>
</td>
</tr>
<tr class="AlertRow">
<td>
<div id="txtAlertMessage" class="AlertTextMessage" />
</td>
</tr>
<tr class="AlertRow">
<td>
<center>
<asp:Button ID="btnClose" runat="server" Text="Close" />
</center>
</td>
</tr>
</table>
</asp:Panel>
</asp:Panel>
<ajaxToolkit:ModalPopupExtender ID="ModalAlertDialog" runat="server" BackgroundCssClass="modalBackground" TargetControlID="NullButton" PopupControlID="AlertPanel" CancelControlID="btnClose" BehaviorID="ModalAlertDialogBehavior" DropShadow="false" />
<asp:Button ID="NullButton" runat="server" Text="" CssClass="AlertNullButton" />

{Note: you will need the css file for the ModalPopupExtender to display correctly. }

Putting all the pieces together:

The button click event calls the ‘DoSomething’ method. The DoSomething method throw an exception . The try catch block in the button click event catches the exception and wraps it in an outer Exception which contains a user friendly message. The ‘AsyncPostBackError’ method passes back the exceptions message and the client side EndRequestHandler checks for the exception and displays the message.

Here is my entire ASP.NET page code:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AlertExample._Default" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<link href="Includes/Stylesheet1.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" onasyncpostbackerror="ScriptManager1_AsyncPostBackError" >
</asp:ScriptManager>
<div>
<script type="text/javascript" language="javascript">
Sys.WebForms.PageRequestManager.getInstance().
add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args)
{
if (args.get_error() != undefined && args.get_error().httpStatusCode == '500')
{
var errorMessage = args.get_error().message
errorMessage = errorMessage.replace('Sys.WebForms.
PageRequestManagerServerErrorException:', "");
args.set_errorHandled(true);
$get("txtAlertMessage").innerHTML = errorMessage;
$find("ModalAlertDialogBehavior").show();
}
}
</script>
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" > <ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="AlertPanel" runat="server" CssClass="modalPopup">
<asp:Panel ID="AlertPanelContent" runat="server" >
<table class="AlertTable">
<tr class="AlertRow" height="20px">
<td class="AlertTitle" height="20px">
<center><asp:Label ID="lblAlertTitle" runat="server" Text="Label" height="20px"/>
</center>
</td>
</tr>
<tr class="AlertRow">
<td>
<div id="txtAlertMessage" class="AlertTextMessage" />
</td>
</tr>
<tr class="AlertRow">
<td>
<center>
<asp:Button ID="btnClose" runat="server" Text="Close" />
</center>
</td>
</tr>
</table>
</asp:Panel>
</asp:Panel>
<ajaxToolkit:ModalPopupExtender ID="ModalAlertDialog" runat="server" BackgroundCssClass="modalBackground" TargetControlID="NullButton" PopupControlID="AlertPanel" CancelControlID="btnClose" BehaviorID="ModalAlertDialogBehavior" DropShadow="false" />
<asp:Button ID="NullButton" runat="server" Text="" CssClass="AlertNullButton" />
</form>
</body>
</html>

And here is my entire codebehind class:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace AlertExample
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
lblAlertTitle.Text = "Alert Example";
}
protected void Button1_Click(object sender, EventArgs e)
{
try
{
DoingSomething();
}
catch (Exception ex)
{
throw new Exception("The system has encountered problems, please notify your administrator or try again.", ex);
}
}
private void DoingSomething()
{
throw new Exception("inner exception message");
}
protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
{
ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message;
}
}
}

And finally the entire CSS:

/*Popup Control*/
/*Modal Popup*/
.modalBackground {
background-color:Gray;
filter:alpha(opacity=70);
opacity:0.7;
}
.modalPopup {
background-color:#FFF;
border-width:1px;
border-style:solid;
border-color:ActiveCaption;
padding:0px;
width:400px;
height:260px;
vertical-align:middle;
}
.AlertOkButton
{
text-align:center;
}
.AlertTable
{
width:100%;
height:100%;
border-spacing:0px;
margin-left:0px;
margin-right:0px;
padding:0px;
}
.AlertRow
{
padding:2px;
}
.AlertTitle
{
background-image:url('../includes/Office2003BlueBG.png');
background-repeat:repeat-x;
background-color:ActiveCaption;
color:White;
font-weight:bold;
width:100%;
height:21px;
max-height:21px;
}
.AlertRow
{
padding:2px;
}
.AlertTextMessage
{
width:350px;
min-height:180px;
max-height:180px;
color:Black;
background-color:#FFF;
padding:0px;
border-spacing:0px;
margin-left:20px;
margin-top:20px;
}
.AlertNullButton
{
visibility:hidden;
}

Sample output of the AJAX Modial Dialog Example

There are a few more tweaks needed to improve how it displays, but I’ll leave that to you. Happy coding!!!

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

Hidden _EventValidation Element Breaks 1.1 Framework Applications on IIS7

Wednesday, August 13, 2008 05:24 | posted by: kevin

Yesterday a few of us at the office had to track down a frustrating bug/feature that prevented ASP.NET 1.1 Framework web application from running on Internet Information Server 7 (IIS7) and Windows Server 2008 (Windows 2008).

Situation:

We host several client sites on our public hosting server. We migrated the 1.1 Framework Applications to Windows 2008 / IIS7 running the pool pipeline in ‘classic mode’. One site appeared to work fine, except that a button on a particular page did now work. It appeared as if the asp:button, which is generated in the HTML as a Submit button, did not post back to the server. The button did work on the Windows Server 2003 / IIS6 environment.

Problem:

We finally determined, after several hours, that the problem was due to:

  • non-standard coding practices of using a ‘get’ action type in a ASP.NET form
  • a very large dropdownlist (more than 2000 records)
  • 2.0 Framework security in IIS7 adding a hidden form element called “__EVENTVALIDATION”.

The combination of these factors together caused an extremely large URL to be created during the ‘get’ request. Large URL’s use to cause buffer overflow issues, so the IIS7 team wisely has added a security feature to reject large URL requests. II7 security rejected our request with a 403 (or possibly a 404) Http error code.

Solutions:

1. You can set your @Page directive to disable event validation for that page - EnableEventValidation = “false”

<%@ Page Language=”vb” AutoEventWireup=”false” Codebehind=”yourpage.aspx.vb” Inherits=”namespace.yourpage” EnableViewState=”false” EnableEventValidation=”false” %>

2. You can set your web.config to disable event validation for that page

<location path="yourpage.aspx"> <system> </system></location> <pages enableeventvalidation="false"></pages>

Note: these solutions are not compatible with II6 and Windows Server 2003!! I do not know of a solution that would be forward and backwards compatible.

A little more about Event Validation from MSDN:

The EnableEventValidation attribute indicates whether event validation should be performed. The default value is true. A Web application can optionally disable event validation to revert to .NET Framework version 1.0 behavior.

Event validation reduces the risk of unauthorized postback requests and callbacks. It instructs ASP.NET to validate only those events that can be raised in the control during a postback request or callback. With this model, a control registers its events during rendering and then validates the events during the post-back or callback handling. All event-driven controls in ASP.NET use this feature by default.

When event validation is enabled a hidden input field is appended on to the bottom of your HTML form like the following:

<input type=”hidden” name=”__EVENTVALIDATION” id=”__EVENTVALIDATION” value=”/wEWigsCgoLO0gICm7n0HQLngYvWCQLogc…”/>

Depending on the size of the content within your controls this may be several hundred or several thousand characters long.

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

CSS Switch Option Due To IE8’s ‘Super Standards Mode’ Default In IE8

Wednesday, March 05, 2008 05:14 | posted by: kevin

Read Best Practices for Version Vector” on the Microsoft IE 8 Readiness Kit web site. Looks like a simple change will allow you to switch the CSS for each client type. Will be a pain, but in the long term this will be a good thing, I think!?! :-)

<head>
<!--[if gte IE 7]>
<link rel="stylesheet" type="text/css" href="stylesheets/ie.css" />
<p>Both Internet Explorer 8 and Internet Explorer 7 will receive this style sheet.</p>
< ![endif]-->
</head>

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

Microsoft released a Beta Release of Internet Explorer 8 today. I have not downloaded it yet, but from everything I’ve read it should be W3C compliant and sport some new features found on other browsers, which should reduce some of the MS haters arguments. I strongly support the current MS strategy of embracing standards, it makes building solutions on MS technology much easier and makes the IT worlds a better place. I will post more after I get my hands on it. I use both IE(6&7) and Mozilla based browsers, depending on what I’m doing and what UI I want for any given task. So I really don’t get too wrapped up in the discussion about which browser is best, no matter how often Joe Healy tries.

Another interesting tidbit is that is that it will default to Acid2 default mode by default and will have three modes as MS states in this press pass:

“Internet Explorer 8 has been designed to include three rendering modes: one that reflects Microsoft’s implementation of current Web standards, a second reflecting Microsoft’s implementation of Web standards at the time of the release of Internet Explorer 7 in 2006, and a third based on rendering methods dating back to the early Web. The newest rendering mode is forward-looking and preferred by Web designers, while the others are present to enable compatibility with the myriad sites across the Web that are currently optimized for previous versions of Internet Explorer.”

Here is a deeper investigation of the impacts of the three rendering modes:

 ”When IE8 eventually ships, it will have three rendering modes, two of which are the already familiar “quirks mode” and “(not so) standards mode.” In an IE team blog entry, IE Platform Architect Chris Wilson revealed a third mode that can be invoked by developers:

  1. “Quirks mode” remains the same, and compatible with current content.
  2. “Standards mode” remains the same as IE7, and compatible with current content.
  3. If you (the page developer) really want the best standards support IE8 can give, you can get it by inserting a simple <meta> element.

This third mode will use a <meta> tag to specify that a page should use the behavior of a specific browser version. To get IE8 really-standard-this-time-we-mean-it behavior, a page will include an element like <meta http-equiv=”X-UA-Compatible” content=”IE=8″ />. That says that a page should use IE8’s behavior—and should use it even in IE9, IE10, or any future version. The first two modes will continue to use the doctype switch to choose between them.”

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

Infragistics and Peter Blum Validation “Page is still loading” Ajax Error

Friday, February 01, 2008 05:01 | posted by: kevin

I recently encountered a compatibility issue with Peter Blum validation controls and Infragistics WARP (Web Async Refresh Panels). Luckily it has already been resolved in the latest version (3.0.11.5000) of Peter Blum’s controls, but it is not documented well on the Peter Blum site or support forums.

If you do not register the WARP panels with the following Peter Blum command you will get “Page is still loading. Please wait” when you try to change data after the page has been updated via a WARP postback.

Steps to reproduce:

If you have a simple page with two WARP panels one that displays the data fields data and the other with a button to update/save.

 

  1. <!--[if !supportLists]--> <!--[endif]-->Load page
  2. <!--[if !supportLists]--> <!--[endif]-->Modify data and press Save via a button in a WARP panel
  3. <!--[if !supportLists]--> <!--[endif]-->WARP panel with data gets updated
  4. <!--[if !supportLists]--> <!--[endif]-->Attempt to change the data.
  5. <!--[if !supportLists]--> <!--[endif]-->Page will show a modal javascript dialog stating, “Page is still loading. Please wait”.
protected void Page_Load(object sender, EventArgs e) { PeterBlum.VAM.AJAXManager.Current.AllInAJAXUpdate = true; PeterBlum.VAM.AJAXManager. UsingInfragisticsAJAX(###WARPPanelName###); //one line for each warp panel PeterBlum.VAM.AJAXManager. UsingInfragisticsAJAX(###SecondWARPPanelName###); //one line for each warp panel }

Tags:

PermaLink   E-Mail Article   RSS Comment Feed  

Large File Uploads in ASP.NET

Wednesday, January 30, 2008 04:58 | posted by: kevin

This will be a quick link to help other folks with a problem I had with a recent project.

If you need to upload a file that is larger than the 4 mb limit default in ASP.NET, there is a great entry at Jon Galloway’s Blog. Go see his site for a great explanation, but here is the solution in a nutshell.

Increase the maxRequestLength for the specific folder within your web site by configuring the following setting in your sites Web.Config.

<location path="MyUploadFolder"> <system> <httpruntime executiontimeout="110" maxrequestlength="20000"> </httpruntime> </system>

Tags:

PermaLink   E-Mail Article   RSS Comment Feed