ASP.Net (& Ajax) Notes

It’s been long enough that the little things tripped me when I fired up a new project… so here they are for “next time”:

  • new Guid() – this probably isn’t the one you want… it initializes to all zeros (i.e. {00000000-0000-0000-0000-000000000000})
    • System.Guid.NewGuid() is the one that generates a fresh unique value
  • Getting “Automatic Compilation” to work (i.e. just uploading your source files to the web server and not your bin folder)
    • Check the <%@ Page > directive & make sure it says CodeFile=”” not CodeBehind=””
    • If not then you’ll be getting errors like “Could not load type …”
    • CodeFile came along with ASP.Net 2.0 and corresponds to a “Web Project” (aka “Web Site”) vs. a “Web Application” which was the only option in ASP.Net 1.x
    • MSDN @ Page Reference 
    • Would love to know what bits need to be twiddled to make CodeFile the default rather than creating a new Web Site project and copying everything over???
    • This guy really goes deep into the differences between Web Sites and Apps <geez, who knew?!?>
  • “Invalid FORMATETC structure”… just reload all the controls in the Ajax toolbox… how annoying
  • “Ajax client-side framework failed to load” error … this is when the shine on all that spiffy new Ajax stuff gets dull in a hurry
    • Absolutely TUUUUNS!! of reasons out there for this… for me it wound up working when I disabled debugging in the web.config on the production server: <compilation debug="False" strict="false"> … ok, yeah, i know that’s not really an answer but i don’t debug on that server anyway so for me it’s a permanent temporary fix 😉
    • Other folks said fire the Add/Remove Programs >  Repair option on .Net Framework 3.5 SP1 (didn’t help for me)
    • or make sure .AXD Extension is setup (was already)
      • IIS6 > {application folder} > (right mouse) Properties > Configuration button > Application extensions
      • IIS7 > Handler Mappings
      • Make sure to uncheck “Verify that file exists”
  • Login / Authentication
    • Great Login control FAQ: http://forums.asp.net/t/1403132.aspx
      • Notably, it shows the necessary “FormsAuthentication.Authenticate(username, password)” bits that’ll let you skip the built in SqlServer Membership support that would otherwise fire by default… handy if you’re going for a quick n’ dirty.
    • Another Q n’ D: throw some hard coded user/passwords under the web.config Forms Authentication tags:     <system.web>
            <authentication mode="Forms">
              <forms>
                <credentials passwordFormat="Clear">
                  <user name="admin" password="" />
                  <user name="user" password="" />
                </credentials>
              </forms>
            </authentication>
    • And on an intranet where everybody is signed into Windows already, just use Windows authentication for a drop dead easy single-sign-on implementation:
      • <authentication mode="Windows">
      • then Page.User.Identity.Name is their Windows login name… just take that and run with it for your own data based role security, etc.
  • Hierarchical Grid aka Nested Collapsable GridViews via Free/Stock ASP.Net AJAX controls
    • Here’s the baseline example that looks really good: http://mosesofegypt.net/post/Master5cDetail-with-CollapsiblePanelExtender-and-edit-detail-with-HoverMenuExtender-using-GridView.aspx
    • My beef was with the HoverMenu… i think it looks cheesy (screenshot, live demo)… i just wanted to use normal <asp:CommandField>’s to edit GridView rows.
    • Problem was, whenever you would click any of the CommandFields links, the corresponding nested GridView and Panel would just “go away” once the Async Postback’s refresh completed… the Panel appeared to be collapsed but even if you tried to expand it the GridView content was totally gone.
    • Banged all around trying to figure out why by debugging through the events that fired… was about to give up and then finally read something that mentioned Submit buttons behave differently than LinkButtons…
    • So I ditched the CommandField and just tossed in my own LinkButtons to do the same thing and voila, the Grid maintains its state… again, who knew!?
  • DataBinding nested controls declaratively – this was a good tip… but only for READ ONLY stuff
    • rather than messing with code behind, just declare your nested List control’s DataSource like this:
    • DataSource='<%#((DataRowView)Container.DataItem).CreateChildView("ProviderOfficeContact")%>’
    • unfortunately the limited way that _RowEditing just tosses all existing data contexts conflicts with this elegant approach, so you can’t go into edit mode with this kind of approach and have to stick with doing the nested DataSource assignment in the parent’s RowDataBound handler.
  • GridView.RowEditing event – you must set a DataSource and re-GridView.DataBind() in order for the the state of the controls to change to edit mode… what an amazingly inefficient architecture they’ve provided with this databinding stuff… you have to keep running back to the database to get data that hasn’t necessarily changed at all
      {
        gvOffices.EditIndex = e.NewEditIndex;
        gvOffices.DataSource = dataset; //DataMember was set initially and thankfully it persists <unlike anything else in this architecture>
        gvOffices.DataBind();
      }
  • GridView.RowUpdating event
    • if we’re manually databinding (vs a DataSource control) we have to to extract values ourselves (i.e. GridViewUpdateEventArgs.NewValues wil be empty)
    • here’s a good reference to get the values out with the minimum of fuss
    • that page also gives a quick blurb on how to access the “DataKeys”: (sender as GridView).DataKeys[e.RowIndex].Values[fieldName]
  • jQuery:
    • don’t forget to set the DOCTYPE!!! I know this is posted all over the jQuery tutorials, but it’s so subtle i keep forgetting and bang my head for a good hour before i remember:
    • live() vs bind() – live() makes sure you bind to elements that might not be currently available… exactly what you need when you’re doing some Ajax that creates elements dynamically (stumbled on this here, thanks Arnold!!)