Monday, October 29, 2007

File Upload not Working on First PostBack after loading Async through ASP.NET UpdatePanel

I was setting up a ASP.NET Wizard control.  The 3rd or 4th step had a file upload control on it, with a runat="server".  The entire wizard control I wrapped in an ASP.NET UpdatePanel so that the wizard was all AJAXified.  I had already fixed the "next" button for this wizard step so that it did a full postback to the server, not an asynchronous one - since I knew that was required to get a file upload to the server.  However, the file was STILL not being posted back, atleast not on the first post.  Subsequent posts would work fine.  On a whim, I looked at the Firebug console to inspect the details of the request while it was in progress (Set a breakpoint in your code somewhere, then look at the Firebug console -- you'll see a "POST" entry with info about what was posted, headers for the request, etc).  Below the POST entry, I saw a warning/error message I had never seen before:

 This page has a file upload.  However, the form tag does not have both the enctype=multipart/form-data and method=POST attributes.  The file will not be uploaded.

Hmm...  I thought about it a bit, and then looked at a normal page I had that had file upload controls on it.  Sure enough, the form tag (there is always just one in ASP.NET) had the enctype attribute set automagically by ASP.NET if ASP.NET knew there was a file upload control on the page.  Otherwise, it leaves it off.  The Async update by the UpdatePanel was loading the FileUpload ok, but wasn't adding the enctype=multipart/form-data to the form tag attributes. 

Solution: manually add the enctype to the page's form on Page_Load()


                                                             
Page.Form.Attributes.Add("enctype", "multipart/form-data");

 
Technorati Tags: , ,

Friday, October 12, 2007

SubSonic Central Database Issues

I like using the SubSonicCentral autoscaffold for playing around with my database. I realize that since I'm already in VS2008, often writing stored procedures in the database, I could just use Visual Studio's built in table data editor for this, but I like how the subsonic scaffold (and the autoscaffold) use the interface to make it easier to select Foreign Key columns, dates, etc. Also, the Visual Studio data editor has a tendency to make a "ghost' image of itself if I let a tooltip come up over any cell in the table, and then plunge my PC into a BSOD.

But one day recently, my SSC on my development PC just stopped working. I would get an error in App_Code\builder.abp (which signifies it is a Subsonic/Database issue) stating "Login failed for user ADAM-IMS\ASPNET". I tried resetting everything (IIS, SQL Express Server, Windows XP!) and still got this message, which cropped up randomly. I made sure EVERY Subsonic configuration was correct, and that the connection strings were correct. I made sure the databases (both my development one and Northwind, which SSC requires for some stuff) were set up with proper permissions for user ASPNET on my machine.

I finally solved the problem days later with a random, hopeless (in my opinion) act. I deleted my "ssc" virtual directory form IIS and remade it, then reset IIS. Ta-da! It started working perfectly again. I doubt this will help anyone else, but just in case I forget I'm posting it here.

UPDATE (8/1/2008): I figured out the problem with the Blue Screen of Death showing up when looking at tables in Visual Studio. Finally did the right google search and came up with this: http://botsikas.blogspot.com/2007/06/ssms-and-win32ksys-blue-screen.html.
Thanks to Andreas Botsikas for figuring this out!


Technorati Tags: , ,


Thursday, October 04, 2007

Setup ddclient for DynDNS and OpenDNS

After googling around a bit, and looking at different examples, I came up with a configuration for ddclient that updates both my companies DynDNS host (which I use to get access to certain intranet stuff from home) and the OpenDNS Dynamic IP address, so OpenDNS can collect stats and customize our experience, etc.  Leave a comment if you need something explained or need more info on how I set ddclient up.  (Note: Values surrounded with [brackets] are names changed to protect the innocent :-)


# Configuration file for ddclient
#
# /etc/ddclient.conf

daemon=300 # check every 300 seconds
syslog=yes # log update msgs to syslog
pid=/var/run/ddclient.pid
ssl=yes

### Select one of these options to determine your IP address
## via hardware interface (if you don't have a router/firewall)
#use=if, if=eth0
## via our CheckIP server

use=web, web=checkip.dyndns.com/, web-skip='Current IP Address: '

## from the status page for a linksys router/firewall
#use=linksys, fw=linksys, fw-login=admin, fw-p

#DynDNS for [dyndns_host_name, e.g. bob.ath.cx or bob.dyndns.org]
################################################################
server=members.dyndns.org
protocol=dyndns2
login=[login]
password=[password]
[dyndns_host_name], [dyndns_host_name_2]

#Dynamic IP for [OPENDNS_NETWORK_NAME] OpenDNS account
######################################################
server=updates.opendns.com
protocol=dyndns2
login=[login]
password=[password]
[OPENDNS_NETWORK_NAME]

 


Technorati Tags: , , ,

Tuesday, October 02, 2007

Self-signed SSL Certificate on Development PC

As I near deployment of a moderately large-scale ASP.NET 2.0 web application, I'm trying to wrap my head completely around all of the issues related to deployment.  One of the questions that keeps boiling up in my mind is how an ASP.NET web application, some of the AJAX stuff, IIS, and SSL all play nice together.

After doing some research online, and even asking some guys that run web sites for a living, I've come to the conclusion that this is definitely something that is best learned by doing.  So, I'm going to attempt to setup the whole package on my development machine.  I know enough about SSL to know that this won't be a perfect simulation.  I'm going to try to generate my own certificate, so I'll just have to pretend like I don't see Firefox telling me that the certificate is not from a trusted source or whatever - if I manage to get that far.  Here goes.

The Self-Signed Certificate

When searching for a method to make my own certificate, a couple of methods were commonly suggested on forums and blog articles:

  • SelfSSL - part of the IIS Resource Kit
  • MakeCert - seems to be bundled with Visual Studio
  • MS Certificate Authority.

I decided to try SelfSSL, since it seems to be the easiest at first glance.  So, I downloaded and installed the IIS Resource Kit (which claims to be for IIS 6.0, but people ay it works fine on Windows XP / IIS 5.1).  I did a custom install and only installed the IIS 6.0 Tools Documentation, SelfSSL, TinyGet, Web Capacity Analysis Tool, and WFetch.  The other stuff sounded useful, but I'll probably just forget about it and only use SelfSSL.

After the install finishes, running SelfSSL from the start menu will bring up a command box with the following info and prompt:

Microsoft (R) SelfSSL Version 1.0
Copyright (C) 2003 Microsoft Corporation. All rights reserved.

Installs self-signed SSL certificate into IIS.
SELFSSL [/T] [/N:cn] [/K:key size] [/S:site id] [/P:port]

/T               Adds the self-signed certificate to "Trusted Certificates"
                 list. The local browser will trust the self-signed certificate
                 if this flag is specified.
/N:cn            Specifies the common name of the certificate. The computer
                 name is used if not specified.
/K:key size      Specifies the key length. Default is 1024.
/V:validity days Specifies the validity of the certificate. Default is 7 days.
/S:site id       Specifies the id of the site. Default is 1 (Default Site).
/P:port          Specifies the SSL port. Default is 443.
/Q               Quiet mode. You will not be prompted when SSL settings are
                 overwritten.

The default behaviour is equivalent with:

selfssl.exe /N:CN=ADAM-IMS /K:1024 /V:7 /S:1 /P:443

C:\Program Files\IIS Resources\SelfSSL>

I decided to be gutsy and try it with all default settings - except to set the validity to 30 days instead of 7.

> selfssl.exe /V:30
> iisreset

Cool beans.  Now, if I look at the "Directory Security" tab in IIS for my default web site (or any of the site under that for that matter) I can click "View Certificate" and see the self-signed certificate I've installed.  There are some errors displayed about it not being from a Trusted Certificate Authority, but I expected that since I made it myself, and didn't get it from a CA like GeoTrust or Thawte or GoDaddy.

I'll try going to https://localhost now - I have just a dummy page set up there in the Default Site.  Ok - two warning dialogs popup.  The first, as I expected, told me that the certificate is not signed by a trusted CA.  The second warns me that the certificate is for ADAM-IMS, but I am viewing localhost.  I want to fix this second one, since Visual Studio usually opens up to localhost when debugging a web application.

> selfssl.exe /N:CN=localhost /V:30
> iisreset

There, that did the trick.  Now I just get the first warning.

Testing the App

Cassini, aka the Visual Studio Development Server, does not currently support SSL (and I doubt it will anytime soon).  Makes sense - it basically opens up a standard http server on a single port (usually 49587 or something like that).  SSL typically runs on port 443 of IIS, separate from the standard http server typically on port 80.  That is why most browsers go to port 80 automatically for http:// and go to port 443 automatically for https:// - of course, Microsoft could write Cassini to support SSL, and make some new convention for what ports are what on Cassini, but I don't think they will anytime soon since you can specify in your project settings that you want to debug your web application using IIS anyhow.  Cassini is for convenience, but you are getting in pretty deep by the time you are thinking about SSL.

So, I set my web app to run on IIS (at localhost/<project_name> for the application root) and fired it up.  Currently, I have to manually switch from http:// to https://, but I'll probably have my Master Page and login page redirect to https:// if a user attempts to connect insecurely.

Things went better than I expected when floating around my application, testing stuff and watching for popup warnings like "This page has encrypted and un-encrypted elements... do you want to display the un-encryted stuff?" I have tried to keep the eventual conversion to secure application in mind, and always follow these conventions:

  • When linking to an image, or another page in the web app, I always use either relative urls [e.g. "img/first.png"] or the ASP.NET application relative path [e.g. "~/dynamics/dynamics.aspx" or
    ResolveUrl("~/somepage.aspx")]
  • I always use relative paths in CSS url("...") values

To be continued?

I'll keep messing around with this, and see if anything else pops up.

Useful things I came across in researching this:

blog.coryisakson.com - MakeCert, and redirecting to https://
Scott Guthrie: Enabling SSL on IIS 7.0 using Self-Signed Certificates - incase you have IIS 7.0, things look much easier
Rob Conery: SSL and Development - SelfSSL, by a guy whose blog I read regularly. Odd and cool that his blog would have this tucked away in the archives. 

Disqus for A Nofsinger's Blog