David Truxall

Adrift in .Net

<September 2008>
SuMoTuWeThFrSa
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011


Navigation

Other Good Blogs

My Other Articles on CodeProject

Subscriptions

News

Day of .Net October 18, 2008 - Be there!
View David Truxall's profile on LinkedIn

Post Categories



ASP.Net (RSS)

A Cool IE HTML/CSS Trick - Conditional Comments

I am continually humbled by the amount of stuff I don't know in the areas where I generally feel good about my level of knowledge....

Today I learned about conditional comments. This is an IE specific trick, but in my case I'm trying to have different CSS for a certain class so it behaves properly in IE6 and standards compliant browsers. The problem is using .png files that have transparency. IE6 totally botches .png files. But it turns out there is an IE-specific filter (progid:DXImageTransform) that causes IE6 to render a .png properly. An older article at A List Apart describes how to use it, along with conditional comments.

Conditional comments allow IE to display the content between the comments based on an expression. In this case, the expression is testing for the browser version:

<!--[if IE 6]>
<link  rel="stylesheet" type="text/css"   href="ie6.css" />
<![endif]-->

So this code snipped would cause IE 6 to load this custom stylesheet. IE7 interprets the comment correctly and doesn't load the stylesheet. Other browsers interpret this as a comment and ignore it. Very nice.

posted Wednesday, August 06, 2008 5:49 PM by davetrux with 0 Comments

MCMS and TFS

Microsoft Content Management Server (MCMS) and Team Foundation Server (TFS) in Visual Studio 2005 don't play nice together. Since MCMS is a dead-end product, I don't expect there will be an actual fix.

The KB Article fix (sort of).

Stefan's workaround. Essentially you need to use them separately, TFS with Visual Studio and a standalone version of the MCMS Template Explorer.

posted Monday, July 07, 2008 5:02 PM by davetrux with 0 Comments

ASP.NET 2.0 and Global.asax: What not to do

I deployed a site today that has some code in the Global.asax event handlers. I let Visual Studio 2008 add the file to my project when I created it, and it put the code directly in the file inside <script runat="server"> tags. I went with it. So when I deployed the file, none of the events fired. Ever. The lesson is: Don't put your code in the global.asax file. Apparently this problem is by design. There is a vague KB Article on this problem, but the solutions aren't all that helpful, I didn't want to pre-compile, and the first solution made no sense at all. A little searching and I found one good solution: put a class that inherits HttpApplication in the App_Code folder as described here. What I don't understand is why Visual Studio adds the file that way if it isn't going to work on an xcopy deployment. Microsoft seems to go out of their way to protect us from ourselves so often that I am surprised the IDE does something intentionally that won't work.

posted Wednesday, February 06, 2008 8:57 AM by davetrux with 0 Comments

ASP.NET Web Project Build Events

I have a web project (the original 2005 web project type, not a web application project) and had a problem getting files copied to the bin directory. Essentially, one of the library projects referenced by the web project has an XML file in the project output, but when the solution is built, the XML file in the bin directory of the library project is not pulled into to the bin directory of the web project. Of course, a post-build event seemed like the thing to do, but web projects don't have support for that.

A little digging and I found this post by Scott Guthrie that describes a "Build Helper Project". You simply add an empty class library project to your solution. You then use the build events in the empty project use to add build events to your web project. You just make sure the project build order is correct so the events get called when you need them.

posted Monday, October 08, 2007 9:28 AM by davetrux with 0 Comments

ASP.NET 404 Errors on the Default.aspx Page

On a new server install, you can copy over the files for your web app and mysteriously get 404 errors. It's a simple configuration in IIS. By default the server is configured not to allow ASP.NET. You simply need to enable this in the IIS management console:

posted Wednesday, August 29, 2007 4:36 PM by davetrux with 0 Comments

Caching Images in IIS 6.0

Yahoo posted a list of rules for improving the performance of your web site, along with a new FireFox-based tool for diagnosing your site's performance, called YSlow.

Their number one rule is to reduce the number of HTTP requests, and this only makes sense. I'll bet most of us ASP.NET developers are well aware of output caching, and how to do this in code. But what about those static files, like images and scripts? Well, there is an IIS setting for that. It's easy to do, and the payoff can be big if you have a very graphic-intense site. Here's what you do for IIS 6:

  1. Open the IIS Management console
  2. Find the directory containing your images (static content only)
  3. Right click the directory, and choose Properties.
  4. Click the HTTP Headers tab.
  5. Check the Enable Content Expiration check box.
  6. Click the Expire After radio button, and choose an interval.
  7. Click the OK button. Done!

The downside is that you won't get the payoff for the first time a user visits the site, but other pages using the same resources will be much snappier. Be aware that caching dynamically created content this way can cause some strange issues, so take care as to what you cache. As always, test it well before you release it and you will be rewarded.

posted Monday, August 20, 2007 9:11 AM by davetrux with 0 Comments

Web Services Authentication Gotcha

We had code in an ASP.NET page trying to call the Commerce Server Profiles web service that resides on the same physical box. The credentials we used were appropriately configured for Commerce Server using AzMan. For some reason, the code was failing with a 401: Unauthorized error. No matter what credentials we used, no luck. But if you ran the code from another box, it worked fine. Same credentials pointing to the service on that box, no errors.

Turns out the hosts file had an entry for the DNS name we were using, and mapped that name to 127.0.0.1, the loopback address. This was the gotcha. Apparently there is a loopback security feature that causes this behavior. There is a support article describing the effect. Essentially it is a security check to keep certain kinds of attacks at bay. The article suggests registry changes to disable it, but we took a different route.  In the short term, if the calling code accessed the web service via IP address (NOT 127.0.0.1) instead of DNS name the problem was circumvented. Meanwhile the network guru is working to get the actual DNS resolution to work.

posted Tuesday, July 03, 2007 4:45 PM by davetrux with 0 Comments

Design with Users In Mind

We all spend lots of time delving into the technical aspects of our work, but don't forget who we are creating all these wonderful apps for. You need to design your apps to work for the users, not create apps that the users need to work to use.

Required Reading: Four Modes of Seeking Information and How to Design for Them

posted Wednesday, January 31, 2007 4:09 PM by davetrux with 0 Comments

ASP.Net Single Sign On - Same Domain

This post in the ASP.Net forums has been the best method for me to make a single-sign on work across different sites in the same domain.

You have to set the machine key in the web.config of all sites even on the same physical box.

posted Wednesday, October 11, 2006 11:11 AM by davetrux with 0 Comments

Don't Re-Invent the Wheel - The .NET Developer's Guide to Identity

Learn how to leverage Active Directory in your .Net apps:

The .NET Developer's Guide to Identity

posted Monday, June 26, 2006 12:08 PM by davetrux with 0 Comments

Free .Net Event in SE Michigan: Day of .Net

I just learned about a FREE .Net training event being held in Ann Arbor, MI on May 13th, 2006: Day of .Net! Check out the agenda at the site.

It is a one-day event advertised as a One Day Conference on all things .NET by Developers for Developers. Lots of great speakers, starting with Mark Miller of Mondays fame, and lots of great local .Net experts, including great guys like Aydin Akcasu, Nino Benvenuti, Dustin Campbell, Jason Follas, Dave Giard, Charles Stacy Harris III, Darrell Hawley, Jim Holmes, Josh Holmes, John Hopkins, Greg Huber, Paul Kimmel, Alex Lowe, Drew Robbins, Martin Shoemaker, and Bill Wagner.

posted Thursday, April 06, 2006 1:32 PM by davetrux with 0 Comments

ASP.Net Windows Authentication and 401.2 Errors

I am working on an ASP.Net app that usesWindows authentication for users. I have a certain section of the app, the "Administration" set of pages that I want to exclude from certain roles of users. This is easy using a web.config file, but the unauthorized users get an ugly default 401.2 error page. I would like to have a custom page for that, and surpisingly there was not a ton of information out there on how to do it. In fact, more often than not the answer was "It can't be done."

I did find an acceptable answer in the forums at aspfree.com. Essentially the solution is to handle the Application_EndRequest event in the global.asax and check the status code and authentication of the user. Here is my version:

void Application_EndRequest(object sender, EventArgs e)
{
    if (Response.StatusCode == 401 && Request.IsAuthenticated && Request.Url.AbsoluteUri.Contains("Administration"))
    {
        Response.ClearContent();
        Server.Execute("../NoAccess.aspx?id=Administration");
    }
}

 

I don't believe this method will work with Forms Authentication, I ran across plenty of posts saying that it works differently.

posted Tuesday, April 04, 2006 12:28 PM by davetrux with 0 Comments

Using XMLHTTP in Javascript

I attended a terrific meeting tonight of GANG, the Great Lakes Area .Net user Group, based in the Detroit-area. The main presenter was Jason Beres who gave an excellent presentation on ASP.Net tricks, many of them utilizing Javascript. One of my favorites came up in discussion and I agreed to post the code snippet here.

I have used this techniqe mainly on classic ASP pages as a way to populate secondary dropdown lists before ASP.Net and control-based postbacks came along. It still works with ASP.Net... BUT...the secondary listbox is not in the Viewstate so it's value isn't set properly when accessing the control in server code on the postback where you handle the data. The secondary list's selected value is still in the Request.Form collection though. It is still a great technique to use to fetch data from the server without reloading the page.

The technique is IE-only as it uses an ActiveX object (XMLHTTP) in the Javascript. It also uses the XML DOM to parse the response from the server. In this example the server is an ASP page, but it could easily be a web service as well with the addition of one a little more code. This code is related to a previous post where I used VBA to enable Excel to be a web service client.

Here is the Javascript function:

/*  Purpose: Fill secondary list boxes with content
    Arguments:  oItem - the primary dropdownlist object
                sFieldName - The name of the field filling the secondary list
                oDestination - the secondary list object
    Returns: None, fills list box using MSXML*/
 
function fillSecondary(oItem, sFieldName, oDestination)
{
  var nValue = oItem[oItem.selectedIndex].value;
  
  var xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
  xmlHTTP.open("POST", "./listboxesXML.asp", false);
  xmlHTTP.send('<' + sFieldName + '>' + nValue + '    
  var xmlDOM = new ActiveXObject("Microsoft.XMLDOM");

  xmlDOM.loadXML(xmlHTTP.ResponseText);

  if (xmlDOM.parseError != 0)
  {
   alert("Error occurred: " + xmlDOM.parseError.reason);
   return false;
  }

  var oNode = xmlDOM.documentElement.firstChild;
  var n=0;
  if(oNode != null)
  {
   //Clear out the secondary list box, it might already have items
   oDestination.length = 0;
   while (oNode != null)
   {
    oDestination[n] = new Option(oNode.text, oNode.attributes(0).text);
    n++;
    oNode = oNode.nextSibling;
   }
   if(n==1)
    oDestination.selectedIndex = 0;
  }
 }

In the HTML on the page, add an OnChange handler to the primary dropdown list to call the Javascript when the user changes the value:


A list Item

The classic ASP page (listboxesXML.asp) called by the Javascript looks like this:

Dim xmlDOM   'XML DOM object
Dim oRS    'Recordset for child records
Dim sXML   'XML String returned to browser
Dim oNode   'DOM node containing data for searching
Dim sType   'The type/name of the unknown child node

set xmlDOM = Server.CreateObject("MSXML2.DOMDocument")
xmlDOM.async = false
xmlDOM.Load Request
xmlDOM.setProperty "SelectionLanguage", "XPath"
if xmlDOM.parseError = 0 then
 'Select the request node
    set oParent = xmlDOM.selectSingleNode("request")
    'Get the child of the request node
    set oNode = oParent.firstChild
    'Store the child's value
    sSearchValue = oNode.Text
    'Store the child's name
    sType = oNode.nodeName

    set oRS = Server.CreateObject("ADODB.recordset")

    'Fetch the appropriate data into the recordset using sType to tell which
    '  secondary list we should be fetching, in this case it is called “secondarytype“

    'ADO Code should be here, removed for brevity

 if not oRS.EOF then
  'Build a response XML string
  sXML = ""
  while not oRS.EOF
   sXML = sXML & "<" & sType & " id=""" & oRS.Fields(0).Value & """>"
   sXML = sXML & Server.HTMLEncode(ors.Fields(1).Value) & "   oRS.MoveNext
  wend
  sXML = sXML & ""
  oRS.Close
 else
  sXML = ""
  sXML = sXML & "<" & sType & " id=""0"">"
  sXML = sXML & "None listed  sXML = sXML & ""
  oRS.Close
 end if
 set oRS = nothing
 Response.Write sXML
else
 Err.Raise 1, "ParseError", "There was a parse error in the request."
end if

This can be very tricky to debug if you have any problems. Try looking at the xmlHTTP.ResponseText in an alert in the Javascript function to see any 500 errors generated by the server.

posted Wednesday, June 16, 2004 7:43 PM by davetrux with 0 Comments

Two Good Solutions for Radio Buttons in a Repeater

Basically, the repeater ignores the GroupName attribute and gives each radiobutton in each row a unique name so they no longer operate as a group. This is an acknowledged bug by Microsoft.

A short, elegant solution posted on the Usenet.

A free control to solve the same problem.

I posted about a similar problem previously with checkboxes and the Repeater, but it was a very different solution than the two I found here.

posted Thursday, March 25, 2004 12:17 PM by davetrux with 1 Comments

Forms Authentication Problem

An ASP.Net site we created is having infrequent problems with logins using forms authentication. Essentially what happens is that the user attempts to login and is successful, but then is redirected back to the login page immediately. So it looks like an infinite loop of logins. We have been able to deduce that the cookie is related to the problem. If the user deletes their cookies in IE the problem goes away. The problem is very intermittent, so it is very difficult to reproduce. It is not generating 500 errors or errors in the logs. From extensive